• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

질문 부탁드립니다

21.09.04 20:48 작성 조회수 174

0

로그인만 구현해볼려고 하는데요

index.js

const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const User = require('./user');

const db = {};
const sequelize = new Sequelize(
config.database, config.username, config.password, config,
);

db.sequelize = sequelize;
db.User = User;

User.init(sequelize);

User.associate(db);

module.exports = db;

user.js

const Sequelize = require('sequelize');

module.exports = class User extends Sequelize.Model {
static init(sequelize){
return super.init({
number: {
type: Sequelize.STRING(11),
allowNull: true,
unique: true,
},
password: {
type: Sequelize.STRING(100),
allowNull: false,
},
birth: {
type: Sequelize.STRING(8),
allowNull: false,
},
provider: {
type: Sequelize.STRING(10),
allowNull: false,
defaultVaue: 'local',
},
gender: {
type: Sequelize.TEXT(''),
allowNull: false,
}
},{
sequelize,
timestamps: true,
underscored: false,
modelName: 'User',
tableName: 'Users',
paranoid: true,
charset: 'utf8',
collate: 'utf8_general_ci',
});
}
}

app.js는 똑같이 했습니다

/Users/yunjin/Desktop/mine/wapeProject/server/models/index.js:17

User.associate(db);

     ^

TypeError: User.associate is not a function

    at Object.<anonymous> (/Users/yunjin/Desktop/mine/wapeProject/server/models/index.js:17:6)

    at Module._compile (node:internal/modules/cjs/loader:1109:14)

    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1138:10)

    at Module.load (node:internal/modules/cjs/loader:989:32)

    at Function.Module._load (node:internal/modules/cjs/loader:829:14)

    at Module.require (node:internal/modules/cjs/loader:1013:19)

    at require (node:internal/modules/cjs/helpers:93:18)

    at Object.<anonymous> (/Users/yunjin/Desktop/mine/wapeProject/server/app.js:11:23)

    at Module._compile (node:internal/modules/cjs/loader:1109:14)

    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1138:10)

[nodemon] app crashed - waiting for file changes before starting...

이렇게 오류가 발생했습니다

그리고 프론트에서 보낸 유저 정보를 어디서 받는지 

잘 모르겠습니다

감사합니다!

답변 1

답변을 작성해보세요.

1

static associate 메서드를 안 만드셔서 에러가 난 겁니다.

프론트에서 보낸 유저 정보는 라우터의 req.body에서 받은 후 passport로 보냈습니다.

김윤진님의 프로필

김윤진

질문자

2021.09.06

const Sequelize = require('sequelize');

module.exports = class User extends Sequelize.Model {
static init(sequelize){
return super.init({
number: {
type: Sequelize.STRING(11),
allowNull: true,
unique: true,
},
password: {
type: Sequelize.STRING(100),
allowNull: false,
},
birth: {
type: Sequelize.STRING(8),
allowNull: false,
},
provider: {
type: Sequelize.STRING(10),
allowNull: false,
defaultVaue: 'local',
},
gender: {
type: Sequelize.TEXT(''),
allowNull: false,
}
},{
sequelize,
timestamps: true,
underscored: false,
modelName: 'User',
tableName: 'Users',
paranoid: true,
charset: 'utf8',
collate: 'utf8_general_ci',
});
}

static associate(db){
 
}
}


user.js 에 associate 안에를 비워놯도 괜찮은가요?

그리고 혹시 프론트에서 axios를 통해 서버로 보낼때 이렇게 작성하는 것이 어디가 틀린지 잘 모르겠어서 질문드립니다

function postUserInfo(){
 
axios({
method: "POST",
url: '../../routes/auth',
data: {
"number": "userNum",
"password": "userPass",
"birth": "userBirth",
"gender": "userGender"
},
withCredentials: true
}).then((res)=>{
console.log(res);
}).catch(error =>{
$joinError.textContent = "입력한 정보가 올바르지 않습니다";
console.log(error);
})

네 비워놔도 상관 없습니다. 프론트에서 보내는 데이터가 진짜로 저것은 아니죠? 정보보호를 위해 바꾸신거죠? URL은 서버 주소를 적으셔야 합니다. 폴더 경로가 아닙니다.

김윤진님의 프로필

김윤진

질문자

2021.09.07

넵 감사합니다
프론트에서 보내는 정보는 변수처리해서 input에 입력하면 들어가게 했습니당

김윤진님의 프로필

김윤진

질문자

2021.09.07

안녕하세요 오류가 발생해서 질문 드립니다

프론트에서 보내는 코드

axios({
method: "POST",
url: "http://localhost:8880",
data: {
"number": "userNum",
"password": "userPass",
"birth": "userBirth",
"gender": "userGender"
},
withCredentials: true
}).then((res)=>{
console.log(res);
}).catch(error =>{
$joinError.textContent = "입력한 정보가 올바르지 않습니다";
console.log(error);
})

서버에서 받는 코드 auth.js

router.post('/join', async(req, res, next)=>{
const { number, password, birth, gender } = req.body;
try{
const exUser = await User.findOne({where : {number}});
if(exUser){
return res.redirect('/join?error=exist');
}
const hash = await bcrypt.hash(password, 12);
await User.create({
number,
password: hash,
birth,
gender,
});
return res.redirect('/');
}catch(error){
console.error(error);
return next(error);
}
});

발생 오류

그리고 추가로 궁금한 게 

만약 url을 localhost8880 저렇게 적는 것이 맞다면

서버에서 어떻게 프론트에서 보낸 정보를 알 수 있는지 모르겠습니다

검색해도 요청 보내는 법 받는 법 이런 것 밖에 나오질 않네요..

 

 

 

 

 

서버 주소가 저게 아닌 것 같은데요? post '/join'으로 만드셨잖아요 그러면 localhost:8080/join이 되어야죠. 다시 한 번 말씀드리지만 폴더경로가 아닙니다. 서버에다 직접 만든 논리적 주소입니다.

요청에서 보낸 데이터는 bodyParser를 통해 파싱(해석)되어서 req.body에 들어갑니다.

김윤진님의 프로필

김윤진

질문자

2021.09.07

감사합니다!
질문 많이 해서 죄송합니다만
앞으로 많이 할것 같습니다..

김윤진님의 프로필

김윤진

질문자

2021.09.07

안녕하세요

CORS 문제가 발생해 해결해볼려고 시도 했습니다

검색해보니 프론트에서 해결 하는 것보단 서버에서 해결하는 것이 쉽다고 해서

npm i cors 하고 app.js에

const cors = require('cors');
 

 

app.use(cors({
origin: 'http://localhost:8880/',
credentials: true
}))

했더니 결과는 같았습니다

그래서

auth.js에 

const cors = require('cors');
 
router.post('/join', cors(),async(req, res, next)=>{
const { number, password, birth, gender } = req.body;
try{
const exUser = await User.findOne({where : {number}});
if(exUser){
return res.redirect('/join?error=exist');
}
const hash = await bcrypt.hash(password, 12);
await User.create({
number,
password: hash,
birth,
gender,
});
return res.redirect('/');
}catch(error){
console.error(error);
return next(error);
}
});

이렇게 해봤지만 실패했습니다

그래서 더 검색해보니 프론트 input에서 보내는 데이터는

Context-Type이 application/json  이고

서버로 보낼 때는 

Context-Type이 application/x-www-from-urlencoded 여야 한다고 하는 것 같습니다

그래서 처음엔

axios({
method: "POST",
url: "localhost:8880/join",
data: encodeURIComponent({
number: "userNum",
password: "userPass",
birth: "userBirth",
gender: "userGender"
}),
// withCredentials: true
}).then((res)=>{
console.log(res);
}).catch(error =>{
$joinError.textContent = "입력한 정보가 올바르지 않습니다";
console.log(error);
})
}

이렇게 encode 해봤지만 실패했고

더 검색해보니 헤더를 추가하라고 하는데 그 다음부터 무슨말인지 모르겠어서 질문 드립니다

감사합니다

참고 사이트 : https://gist.github.com/jays1204/703297eb0da1facdc454

 

 

 

axios url 앞에 http:// 붙여보세요. Content-Type은 말도 안되는 소리니 무시하세요. 주소가 같으면 cors도 필요없습니다.

김윤진님의 프로필

김윤진

질문자

2021.09.08

안녕하세요 http:// 붙이면 처음 문제인 404 에러가 발생합니다

제로초님 블로그에 있는 CORS 설명하신거 보고 따라해 봤습니다

 

크롬 등의 브라우저는 localhost에서는 CORS 요청이 안 되도록 막아두기도 하여 저렇게 허용을 해줘도 안 될 수도 있습니다. localhost의 경우에는 안 돼도 너무 당황하지 맙시다.

또한 CORS 외에도 CORB(cross origin read blocking) 현상도 있습니다. CORS를 허용했더라도 POST, PUT, DELETE 요청에서 json을 전송하는 경우 요청이 차단됩니다. 이럴 때는 json 대신 www-form-urlencoded 형식으로 데이터를 보내면 됩니다.

 

이렇게 말씀하셔서 

코드는


axios({
url: "localhost:8880/join",
method: "POST",
// contentType: application/x-www-form-urlencoded, encodeURIComponent
data: encodeURIComponent({
number: "userNum",
password: "userPass",
birth: "userBirth",
gender: "userGender"
}),
// withCredentials: true
}).then((res)=>{
console.log(res);
}).catch(error =>{
$joinError.textContent = "입력한 정보가 올바르지 않습니다";
console.log(error);
})
}

에러

혹시 request header에 

Accept와 Context-Type이 둘다 

application/json 이거나 

application/x-www-form-urlencoded 여야 하나요?

일단 시도해 본것은 프론트에서 보낼 데이터 앞에 encodeURIComponent

이거를 지우고도 해봤는데 실패했습니다

블로그에 있는 방법 다 해봤는데 왜그럴까요?

로컬호스트라서 그냥 불가한거 일까요? 

감사합니다!

 

 

 

http:// 붙이셔야하고요. cors랑 상관없는 에러입니다. content-type이랑도 상관없고요. 404 에러가 뜨는건 서버 주소를 잘못 적으셔서 그런겁니다. /join 앞에 뭘 더 적으셔야할텐데요. 제 강좌에 router.use랑 주소 합쳐진다고 했던거 기억하시나요?

김윤진님의 프로필

김윤진

질문자

2021.09.09

넵 그래서 url 코드를 http://localhost:8880/auth/join

이렇게 적었더니

500 Internal Server Error
 

500 에러가 발생했습니다

산 넘어 산이네요..

 

Request Payload를 보니 데이터는 정상적으로 들어가 있어

서버쪽 문제 인것 같습니다

제가 코드를 잘못 적은 걸까요? 똑같이 따라치긴했습니다

app.js

app.use('/', loginRouter);
app.use('/auth', authRouter);

auth.js


router.post('/join', async(req, res, next)=>{
console.log("AA")
const { number, password, birth, gender } = req.body;
try{
const exUser = await User.findOne({where : {number}});
if(exUser){
return res.redirect('/join?error=exist');
}
const hash = await bcrypt.hash(password, 12);
await User.create({
number,
password: hash,
birth,
gender,
});
return res.redirect('/');
}catch(error){
console.error(error);
return next(error);
}
});

 

서버에사 에러가 났으니 서버 에러 메시지를 주셔야죠

김윤진님의 프로필

김윤진

질문자

2021.09.09

이렇게 왔습니다

서버 에러 메시지는 서버 콘솔에서 보셔야죠

김윤진님의 프로필

김윤진

질문자

2021.09.09

아항..

첫번째 줄 해석해보니 기본엔진이 지정되어 있지 않아 확장이 제공되지 않았다고 뜹니다

제 생각으로는 app.set('view engine', 'html')

이 코드를 작성하지 않아 그런 것 같습니다

 

이 코드 추가해서 시도해보니 'html' 모듈을 찾을 수 없다고 나옵니다

흠..여기서 어떻게 해야할까요?

html은 ejs같은 뷰 엔진이 아닙니다. html은 res.sendFile해주면 되므로 뷰 엔진을 설정할 필요가 없습니다.

그리고 위에 provider cannot be null도 provider 자리에 null이 들어가서 그렇습니다. 값을 넣으세요.

김윤진님의 프로필

김윤진

질문자

2021.09.10

안녕하세요

 

mysql workbenrch user table입니다

local이 provider인데 provider는 제대로 들어간거 맞나요?

 

오류는 동일하게 발생합니다

No default engine was specified and no extension was provided.

provider를 이렇게 했는데 왜 null이 나오는 걸까요?

500에러가 발생했는데 왜 데이터베이스에 들어갈 수 있는건갸요?

그리고 보여주고 싶은 html들을 views 폴더에 꼭 넣어야 하는건 아니죠?

provider: {
type: Sequelize.STRING(10),
allowNull: false,
defaultValue: 'local',
},

추가로

const router = express.Router();
//cors({ origin: 허용 오리진 주소 }) 나중에 실제 도메인에 올릴 땐 이렇게
router.post('/join', async(req, res, next)=>{
console.log("AA")
const { number, password, birth, gender } = req.body;
try{
const exUser = await User.findOne({where : {number}});
if(exUser){
// return res.redirect('/join?error=exist');
return res.status(406).json({message: "Same ID"})
}
const hash = await bcrypt.hash(password, 12);
await User.create({
number,
password: hash,
birth,
gender,
});
return res.redirect('/');
}catch(error){
console.error(error);
return next(error);
}
});

회원가입하려는 id가 이미 존재한다면

프론트로 보내주는 코드를  return res.status(406).json({message: "Same ID"})

적었는데 406오류는 가는데 json은 가지 않습니다

왜그런건가요?

 

provider를 이렇게 했는데 왜 null이 나오는 걸까요?

500에러가 발생했는데 왜 데이터베이스에 들어갈 수 있는건갸요?

- 데이터 안 들어갔습니다. 기존에 들어간 건 provider를 제공해서 문제가 없고, 새로 넣은게 안 들어간 겁니다.

No default engine was specified and no extension was provided.

- 소스코드 중에 res.render 쓰고 있는게 있나요? 그러면 다시 뷰 엔진 연결하셔야 합니다.

그리고 보여주고 싶은 html들을 views 폴더에 꼭 넣어야 하는건 아니죠?

- 템플릿 파일만 views에 넣는겁니다(res.render). html은 정적파일이라서 아무데나 넣고 쓰시면 됩니다(res.sendFile).

적었는데 406오류는 가는데 json은 가지 않습니다 왜그런건가요?

- json 갔을겁니다. 받는 부분 코드가 문제거나, 페이지가 이동되는 요청이라 받을 수 없었을 겁니다. 다시 말씀드리지만 return res.redirect('/join?error=exist'); 이게 답입니다.

제 강좌에 이렇게 해서 프론트에서 에러 메시지 띄우는 것까지 전부 다 있습니다.

김윤진님의 프로필

김윤진

질문자

2021.09.11

감사합니다 모두 해결되었습니다!