ABOUT ME

개발 공부를 위한 블로그입니다. https://github.com/youngjaekim22

Today
Yesterday
Total
  • 토큰 생성
    Study/Node, React 기초 강의_John Ahn 2023. 2. 19. 11:24

    JSONWEBTOKEN 라이브러리 설치

    npm install jsonwebtoken --save

     

     

    User.js에 토큰 생성함수 추가

    // mongoose를 요청함
    const mongoose = require('mongoose');
    
    // bcrypt를 요청
    const bcrypt = require('bcrypt');
    
    // Salt를 이용해서 비밀번호를 암호화 해야하기 때문에 saltRounds를 설정
    const saltRounds = 10
    
    // jsonwebtoken 요청
    const jwt = require('jsonwebtoken');
    
    // Schema 설정
    const userSchema = mongoose.Schema({
        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
        },
        image: String,
        token: {
            type: String
        },
        tokenExp: {
            type: Number
        }
    })
    
    // user 정보를 저장하기전에 비밀번호를 암호화시킨다.
    userSchema.pre('save', function (next) {
        // userSchema를 가져옴
        var user = this;
    
        // 비밀번호를 바꿀때만 암호화한다.
        if (user.isModified('password')) {
    
            // 비밀번호를 암호화 시킨다.
            bcrypt.genSalt(saltRounds, function (err, salt) {
                if (err) return next(err)
    
                bcrypt.hash(user.password, salt, function (err, hash) {
                    if (err) return next(err)
                    user.password = hash
                    next()
                })
            })
        }
        else {
            next()
        }
    })
    
    // 비밀번호가 맞는지 확인하는 함수
    userSchema.methods.comparePassword = function (plainPassword, cb) {
    
        // plainPassword : 입력하는 비밀번호
        // 암호화된 비밀번호 : DB에 있는 비밀번호
    
        bcrypt.compare(plainPassword, this.password, function (err, isMatch) {
            if (err) return cb(err);
            cb(null, isMatch)
        })
    }
    
    // 토큰 생성 함수
    userSchema.methods.generateToken = function (cb) {
    
        var user = this;
    
        // jsonwebtoken을 이용해서 token을 생성하기
        var token = jwt.sign(user._id.toHexString(), 'secretToken')
    
        user.token = token
    
        user.save(function (err, user) {
            if (err) return cb(err)
            cb(null, user)
        })
    }
    
    // Schema를 모듈로 감싸 줌
    const User = mongoose.model('User', userSchema)
    
    // 모듈을 다른 곳에서도 사용할 수 있도록 하는 코드
    module.exports = { User }

     

    cookie-parser 설치

    npm install cookie-parser --save

     

    cookieParser 추가 및 토큰 생성 기능 구현

     

     

    index.js

     

    // express 모듈을 추가
    const express = require('express')
    // 새로운 express 모듈을 생성
    const app = express()
    // port 설정
    const port = 5000
    // User 모델을 가져옴
    const { User } = require("./models/User");
    // bodyPaser를 가져옴
    const bodyPaser = require("body-parser");
    // config를 가져옴
    const config = require('./config/key');
    // cookieParser를 가져옴
    const cookieParser = require("cookie-parser");
    
    // bodyPaser 옵션주기
    // application/s-www-form-urlencoded
    app.use(bodyPaser.urlencoded({ extended: true }));
    // application/json
    app.use(bodyPaser.json());
    app.use(cookieParser());
    
    // mongoose 연결
    const mongoose = require('mongoose')
    // error 발생을 막기 위한 코드
    mongoose.connect("mongodb+srv://<아이디>:<비밀번호>@boilerplate.6t2ootw.mongodb.net/?retryWrites=true&w=majority"
    ).then(() => console.log('MongoDB Connected...'))      // DB 연결 확인을 위한 코드
        .catch(err => console.log(err))
    
    // Hello World! 전송
    app.get('/', (req, res) => {
        res.send('Hello World!!')
    })
    
    app.post('/register', (req, res) => {
    
        // 회원 가입 할때 필요한 정보들을 client에서 가져오면 그것들을 데이터 베이스에 넣어준다.
    
        const user = new User(req.body)
    
        user.save((err, userInfo) => {
            if (err) return res.json({ success: false, err })
            return res.status(200).json({
                success: true
            })
        })
    })
    
    app.post('/login', (req, res) => {
        User.findOne({ email: req.body.email }, (err, user) => {
    
            // 요청된 이메일을 데이터베이스에서 있는지 찾는다.
            User.findOne({ email: req.body.email }, (err, user) => {
                if (!user) {
                    return res.json({
                        loginSuccess: false,
                        message: "제공된 이메일에 해당하는 유저가 없습니다."
                    })
                }
            })
    
            // 요청된 이메일이 데이터 베이스에 있다면 비밀번호가 맞는 비밀번호 인지 확인.
            user.comparePassword(req.body.password, (err, isMatch) => {
                if (!isMatch)
                    return req.json({ loginSuccess: false, message: "비밀번호가 틀렸습니다." })
    
                // 비밀번호 까지 맞다면 토큰을 생성하기.
                user.generateToken((err, user) => {
    
                    if (err) return res.status(400).send(err);
    
                    // 토큰을 저장한다. 어디에? 쿠키 or 로컬스토리지
                    res.cookie("x_auth", user.token)
                        .status(200)
                        .json({ loginSuccess: true, userId: user._id })
                })
    
            })
        })
    })
    
    // 5000번 port에서 실행
    app.listen(port, () => {
        console.log(`Example app listening on port ${port}`)
    })

     

    TEST

     

     

    'Study > Node, React 기초 강의_John Ahn' 카테고리의 다른 글

    auth 기능 구현  (0) 2023.02.19
    로그인 기능 구현  (0) 2023.02.19
    Bcrypt를 이용한 비밀번호 암호화  (0) 2023.02.19
    비밀 설정 정보 관리  (0) 2023.02.19
    Nodemon  (0) 2023.02.14
Designed by Tistory.