Frontend/react

로그인 기능(유저정보, 비밀번호 비교, 토큰 생성)

dddzr 2022. 7. 5. 23:13

1. login 라우터 생성

User.findOne으로 req로 받은 email의 정보를 DB에서 찾음.

index.js

const express = require('express');//express안에 body-parser포함되서 따로 안써도 된다고함
const app = express();
const port = 3000 //아무 포트번호 지정
const cookieParser = require('cookie-parser');
const { User } = require('./models/User');
const config = require("./config/key")

app.post('/login', (req, res) => { //라우터의 endpoint가 register
  // const user = new User(req.body);
  
  // 요청된 이메일 데이터 베이스에 있는지 찾기
    User.findOne({ email: req.body.email }, (err, userInfo)=>{
      console.log(userInfo)
      if(!userInfo){
        return res.json({
          loginSuccess: false,
          message: "등록되지 않은 이메일입니다."
        })
      } 
      // else {
        // 비밀번호가 일치하는지 확인
        userInfo.comparePassword(req.body.password, (err, isMatch) => {//User.js에서 선언한 함수
          if (!isMatch)
            return res.json({ loginSuccess: false, message: "틀린 비밀번호입니다." })

          //토큰생성
          userInfo.generateToken((err, user) => {//User.js에서 선언한 함수
            if (err) return res.status(400).send(err);

            //토큰을 저장 -> 쿠키/로컬스토리지 등
            // localStorage.setItem()
            res.cookie("x_auth", user.token)
              .status(200)
              .json({ loginSuccess: true, userId: user._id });


          })
        })
      // }
    })
})

 

2. comparePassword 함수 구현

3. generateToken 함수 구현

User.js

const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const saltRounds = 10; //sort의 글자 수
var jwt = require('jsonwebtoken');

const userSchema = mongoose.Schema({
    name: {
        type: String,
        maxlength: 50,
        // required: true
    },
    email: {
        type: String,
        trim: true,
        unique: 1
    },
    password: {
        type: String,
        minlength: 5,
        // required: true
    },
    role: {
        type: Number,
        default: 0
    },
    image: String,
    token: {
        type: String
    },
    tokenExp:{
        type: Number
    }
})


userSchema.pre('save', function(next){//mongoose의 pre함수 이용, 파라미터 next(다음에 실행 할 함수)
    var user = this;//this는 userSchema
    
    //이 함수는 user정보가 수정되어 저장될때도 실행됨.
    if(user.isModified('password')){//비밀번호가 변경 되었을 때만 비밀번호 암호화한다는 조건절
        bcrypt.genSalt(saltRounds, function(err, salt) {//saltRounds길이의 salt 생성
            if(err) return next(err); //next 함수 실행
            bcrypt.hash(user.password, salt, function(err, hash) {
                if(err) return next(err);
                user.password = hash;
                console.log(user.password);
                next();
            });
        });
    }else {
        next();
    }
})

userSchema.methods.comparePassword = function (plainPassword, callback) {//함수이름 상용자 정의
    console.log(plainPassword + " @ " + this.password);
    console.log(this);
    bcrypt.compare(plainPassword, this.password, function(err, isMatch){
        console.log(isMatch);
        if(err) return callback(err);
        callback(null, isMatch)//isMatch 는 true
    })

}

userSchema.methods.generateToken = function(callback) {//함수이름 상용자 정의
    var user = this;
    var token = jwt.sign(user._id.toHexString(), 'secretToken');//toHexString없으면 Error: Expected "payload" to be a plain object.
    //user._id, 'secretToken' 두개합쳐서 토큰 만듬. secretToken에 아무거나 문자열 넣으면 됨.
    user.token = token;
    user.save(function(err, user){
        if(err) return callback(err);
        callback(null, user);
    })
}

const User = mongoose.model('User', userSchema) //모델이름, 스키마

module.exports = {User} //다른 곳에서도 쓸수 있도록 export

 

3-1. Json WebToken 라이브러리 다운로드

npm install jsonwebtoken --save

 

 

https://www.npmjs.com/package/jsonwebtoken

 

jsonwebtoken

JSON Web Token implementation (symmetric and asymmetric). Latest version: 8.5.1, last published: 3 years ago. Start using jsonwebtoken in your project by running `npm i jsonwebtoken`. There are 19801 other projects in the npm registry using jsonwebtoken.

www.npmjs.com

 

3-2. token 저장

토큰을 저장할 수 있는 곳은 많은데

개발자 모드 (크롬 f12)에서 storage중에 한곳에 저장하면 됨.

(세션, 쿠키가 대표적)

 

쿠키에 저장하려면 cookie-parser 다운로드 해야함

npm install cookie-parser --save

 

4. req Test

 

 

'Frontend > react' 카테고리의 다른 글

logout 기능 (로그아웃)  (0) 2022.07.07
Auth (인증/인가)기능  (0) 2022.07.07
bcrypt 정보 암호화  (0) 2022.06.26
비밀 정보 보호 (DB 계정 정보 보호)  (0) 2022.06.23
NODE MON  (0) 2022.06.23