반응형
boilerplate 유튜브 강의 시리즈
Blog ReactJS NodeJS#13 LOGIN FUNCTION WITH JSONWEBTOKEN
이번 강의에서는 JWT(jsonwebtoken)을 사용하여 로그인을 구현한다.
JWT는 정보를 안전하게 전송하기 위해 정의된 공개된 표준 (RFC 7519) 이다. (자세한 설명은 여기)
1. jsonwebtoken 모듈 및 type definition 패키지 설치
npm i -S jsonwebtoken
npm i -D @types/jsonwebtoken
2. UserSchema에 로그인 시 사용할 comparePassword, generateToken 메소드 추가
jsonwebtoken 모듈을 import 하고 UserSchema에 comparePassword, generateToken 메소드를 추가한다.
추가한 메소드의 타입은 IUser 인터페이스에도 정의해준다.
import { Schema, Model, model, Document, HookNextFunction } from 'mongoose';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
const saltRounds = 10;
export interface IUser extends Document{
name: string;
email: string;
password: string;
lastname: string;
role: number;
token: string;
tokenExp: number;
comparePassword: (plainPassword:string, cb:Function) => void;
generateToken: (cb:Function) => void;
}
const UserSchema: Schema<IUser> = new Schema<IUser>({
name: {
type:String,
maxlength:50
},
email: {
type:String,
trim:true,
unique: 1
},
password: {
type:String,
minlength: 5
},
lastname: {
type:String,
maxlength: 50
},
role: {
type:Number,
default: 0
},
token: {
type:String,
},
tokenExp: {
type: Number
}
});
UserSchema.pre<IUser>('save', function(next:HookNextFunction){
if(this.isModified('password')){
bcrypt.genSalt(saltRounds, (err:Error, salt:string)=>{
if(err) return next(err);
bcrypt.hash(this.password, salt, (err:Error, hash:string)=>{
if(err) return next(err);
this.password = hash;
next();
})
})
}else{
next();
}
});
UserSchema.methods.comparePassword = function(plainPassword:string, cb:Function){
bcrypt.compare(plainPassword, this.password,(err:Error, isMatch:boolean)=>{
if(err) return cb(err);
cb(null, isMatch);
});
}
UserSchema.methods.generateToken = function(cb:Function) {
this.token = jwt.sign(this._id.toHexString(), 'secret');
this.save((err:Error, user:IUser)=>{
if(err) return cb(err);
cb(null, user);
})
}
export const User: Model<IUser> = model<IUser>('User', UserSchema);
3. index.ts에 로그인 api 추가
위에서 추가한 2가지 메소드를 로그인 로직에서 활용한다.
코드를 살펴보면 첫 번째로 email 검증을 하고 두 번째로 comparePassword 메소드로 패스워드 검증을 한다.
마지막으로 generateToken 메소드로 token을 생성하고 token을 담아 반환한다.
app.post('api/user/login', (req:express.Request, res: express.Response)=>{
User.findOne({email: req.body.email}, (err:Error, user:IUser)=>{
if(!user){
return res.json({
loginSuccess: false,
message: "Auth failed, email not found"
});
}
user.comparePassword(req.body.password, (err:Error, isMatch:boolean)=>{
if(!isMatch){
return res.json({ loginSuccess: false, message: "wrong password"});
}
})
user.generateToken((err:Error, user:IUser)=>{
if(err) return res.status(400).send(err);
res.cookie("x_auth", user.token)
.status(200)
.json({
loginSuccess: true
})
})
})
})
반응형
'IT > 프로젝트' 카테고리의 다른 글
10. boilerplate - 로그아웃 구현 (0) | 2020.11.22 |
---|---|
9. boilerplate - 미들웨어에 authorization 추가하기 (0) | 2020.10.30 |
7. boilerplate - 해시 패스워드 with BCRYPT (0) | 2020.10.22 |
6. boilerplate - 보안 파일 with ENV file (0) | 2020.10.21 |
5. boilerplate - tsc-watch 설치 (0) | 2020.10.21 |