node.js에서 mongoose만 사용하면 잘되는데,
passportLocalMongoose를 추가해서 사용하면 컬렉션이 만들어 지지 않을 때 가 있다.
왜 안되는지 알아보고 예제를 통해 해결하자.
문제점 은 2개다.
1. 필수 필드 지정 문제
2. 사용자 등록 라우터에서 필드명과 클라이언트 데이터 일치 문제
1. 필수 필드 지정 문제
- 일반적인 mongoose 스키마 정의
일반적인 mongoose 필수 필드 지정 방법은 required: true 옵션을 사용하여 개발자가 지정한다.
컬렉션 생성 시 필수 필드를 사용하지 않으면 에러가 발생한다.
const mongoose = require("mongoose");
let UserSchema = new mongoose.Schema({
userId: {
type: String,
required: true //필수 필드 지정
},
password: {
type: String,
required: true //필수 필드 지정
},
nickName:type: String,
});
let User = mongoose.model("User", UserSchema);
module.exports = User;
- passportLocalMongoose 과 함께 mongoose 스키마 정의
하지만 passportLocalMongoose 사용시 자동으로 username과 password 필수 필드로 추가 되어 꼭 작성해 줘야 한다.
또한 일반적인 mongoose 스키마 정의와 다르게 이미 필수 필드로 지정되어 있기 때문에 required:true 옵션을 쓰지 않는다.
따라서 필수 필드인 username과 password를 작성하지 않으면 컬렉션 생성 시 에러가 발생한다.
이게 첫번째 주의 할 점이다.
const mongoose = require("mongoose");
const passportLocalMongoose = require("passport-local-mongoose"); //passportLocalMongoose 사용
let UserSchema = new mongoose.Schema({
username: String, //필수 필드
password: String, //필수 필드
userNickname: String,
});
UserSchema.plugin(passportLocalMongoose);
let User = mongoose.model("User", UserSchema);
module.exports = User;
2. 사용자 등록 라우터에서 필드명과 클라이언트 데이터명 비일치 문제
- 문제점
현재 코드에서는 클라이언트에서 전송한 데이터를 req.body.userId, req.body.userpassword로 받아오고있다.
그런데 mongoose 스키마는 username, userpassword 필수 필드명을 정의하고 있어서 req.body.userId, req.body.userpassword 와 필드명이 일치 하지 않는다.(예제 주석 참조)
물론 일반적인 mongoose 에서는 일치 하지 않아도 되지만 passportLocalMongoose 사용 시에는 문제가 생긴다.
router.post("register", (req, res) => {
if (
req.body.userId &&
req.body.userNickname &&
req.body.userpassword
) {
let newUser = new User({
username: req.body.userId, //필수 필드 명이 일치 하지 않아 에러 발생
userNickname: req.body.userNickname, //얜 일치 하지 않아도 됨
});
return createUser(newUser, req.body.userpassword, req, res);
}
});
- 해결 방법
클라이언트에서 전송한 데이터의 필드명을 몽구스 스키마에서 정의한 필드명과 일치시켜 줘야한다.
필드명과 데이터명이 다르면 에러 발생.
사용자 등록 라우터 예제
router.post("/user/register", (req, res) => {
if (
req.body.username &&
req.body.userNickname &&
req.body.userpassword
) {
let newUser = new User({
username: req.body.username, //필드명과 클라이언트에서 전송한 데이터 이름을 일치 시켜준다.
userNickname: req.body.userNickname,
});
return createUser(newUser, req.body.userpassword, req, res);
}
});
클라이언트 전송 데이터 예제
8번째 줄에 <input>태그 name을 username으로 지정.
13번째 줄에 <input>태그 name을 password로 지정.
<body>
<div>
<h2>Sign up</h2>
<form method="post" action="/register" id="register-form ">
<div>
<label for="username-register">아이디</label>
//mongoose.js의 username 필드와 똑같이 name="username" 지정
<input id="username-register" type="text" name="username" placeholder="Id">
</div>
<div>
<label for="Password-register">비밀번호</label>
//mongoose.js의 password 필드와 똑같이 name="password" 지정
<input id="Password-register" type="password" name="password" placeholder="Id">
</div>
<div>
<label for="Nickname-register">닉네임</label>
<input id="Nickname-register" type="text" name="nickname" placeholder="Id">
</div>
<button id="register" type="submit" name="register">Sign up</button>
</form>
</div>
</body>
정리 : 라우터에서 필수 필드명과 클라이언트 데이터 이름을 일치 시켜준다.
3. 예제 코드
위에서 설명한 것들을 담은 예제 코드다. 주석을 잘 볼것.
- mongoose.js
username과 password는 필수 필드 이므로 꼭 작성해줘야 한다.
- register.ejs
이 코드는 html이라고 생각하고 봐도 무관하다.
아이디의 name ="username"
비밀번호의 name ="password" 로 지정 해줘서 필수 필드와 이름을 일치 시켜준다.
- user.js
컬렉션을 만드는 부분의 일부다.
mongoose.js의 필수 필드인 username과 register.ejs의 input인 username이 똑같은 이름인 것을 볼 수 있다.
'node.js' 카테고리의 다른 글
[node.js] npm WARN using --force Recommended protections disabled. 에러 해결 (0) | 2024.01.31 |
---|