주뇽's 저장소

#8 로그인 기능JWS(ReactJS) 본문

웹개발/React

#8 로그인 기능JWS(ReactJS)

뎁쭌 2023. 1. 8. 18:50
728x90
반응형

본 정리는 인프런 John Ahn 따라하며 배우는 노드, 리액트 시리즈 - 기본 강의를 참고하였습니다.

  • 전체 흐름도스크린샷 2022-12-28 오후 8 31 25
  1. 요청된 이메일을 데이터베이스에서 찾기
  2. //몽고DB에서 제공하는 find함수 사용 // 1. 요청된 이메일을 데이터베이스에서 찾기 User.findOne({email: req.body.email}, (err, user)=>{ if(!user){ return res.json({ loginSuccess : false, massage : "제공된 이메일에 해당하는 유저가 없음" }) }
  3. 요청된 이메일이 있다면 비밀번호 체크
     // Model/User.js 
     userSchema.methods.comparePassword = function(plainPassword,callbackfunk)
     {
         // plainPassword = 1234
         // database 암호 = 암호화된 비밀번호 
    
         bcrypt.compare(plainPassword, this.password, function(err, isMatch){
             if(err){
                 return callbackfunk(err);
             }
             else
                 callbackfunk(null, isMatch);
         })
     }
     // index.js파일 수정
     // 2. 요청된 이메일이 있다면 비밀번호 체크
         user.comparePassword(req.body.password, (err,isMatch)=>{
           if(!isMatch){
             return res.json({
               loginSuccess : false,
               massage : "비밀번호가 틀립니다"
             })
           }
  4. 새로운 함수 생성(Model/User.js)파일 수정
  5. 위 조건을 모두 만족하면 Token 생성토큰 저장용 cookie-parser 라이브러리 설치새로운 함수 생성(Model/User.js)파일 수정
     // index.js파일 수정
     const cookieParser = require('cookie-parser');
     app.use(cookieParser());
    
     // 3. 위 조건을 모두 만족하면 Token 생성
           user.generateToken((err,user)=>{
             if(err) return res.status(400).send(err)
             // 현재 user에는 토큰이 있음 토큰을 쿠키에 저장
             res.cookie("x_auth",user.token).status(200).json({
               loginSuccess : true,
               userID : user._id 
             })        
           })
    • 전체 코드 (User.js)
    • const mongoose = require('mongoose'); const bcrypt = require('bcrypt'); const saltRounds = 10; // 10자리를 이용하여 생성 const jwt = require('jsonwebtoken'); const userSchema = mongoose.Schema({ name:{ type : String, maxlength : 50, }, email:{ type : String, trim : true, // space를 없애주는 역할 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, }, }) userSchema.pre('save', function(next){ 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,callbackfunk) { // plainPassword = 1234 // database 암호 = 암호화된 비밀번호 bcrypt.compare(plainPassword, this.password, function(err, isMatch){ if(err){ return callbackfunk(err); } else callbackfunk(null, isMatch); }) } userSchema.methods.generateToken = function(callbackfunk){ //jsonwebtoken을 이용하여 토큰 생성 var user = this; var token = jwt.sign(user._id.toHexString(), 'secretToken') // user._id + 'secretToken' = token // user.id + secretToken 을 이용하여 토큰을 생성하고 나중에 secretToken을 이용하여 user.id 확인 가능 user.token = token user.save(function(err, user){ if(err) return callbackfunk(err) callbackfunk(null, user) }) } const User = mongoose.model('User', userSchema) //스키마를 모델로 감싸줌 module.exports = {User} //다른곳에서 사용할 수 있게 하기위해
    • 전체 코드 (index.js)
    • const express = require('express'); const app = express(); const port = 3000 const mongoose = require('mongoose'); const {User} = require("./Models/User");// 미리 정의했던 모델 가져오기 const bodyParser = require('body-parser'); const config = require("./config/key"); const e = require('express'); const cookieParser = require('cookie-parser'); // 데이터 분석을 위한 추가 설정 app.use(cookieParser()); app.use(bodyParser.urlencoded({extended:true})); app.use(bodyParser.json()); mongoose.set('strictQuery',true) mongoose.connect(config.mongoURI, { useNewUrlParser: true, useUnifiedTopology: true }).then(() => console.log('Successfully connected to mongodb')) .catch(e => console.error(e)); app.get('/', (req, res) => { res.send('Hello World!') }) app.post('/api/users/register', (req,res) =>{ // 회원 가입할 때 필요한 정보들을 클라이언트로부터 받으면 데이터베이스에 정보 저장 // 미리 정의했던 모델을 가져와야 함 const user = new User(req.body); user.save((err, userInfo) =>{// user모델에 정보들 저장 //만약 에러가 발생 시 json형식으로 에러와 에러메시지 전달 if(err) return res.json({success:false, err}) return res.status(200).json({ success:true }) }) }) app.post('/api/users/login', (req, res) => { // 1. 요청된 이메일을 데이터베이스에서 찾기 User.findOne({email: req.body.email}, (err, user)=>{ if(!user){ return res.json({ loginSuccess : false, massage : "제공된 이메일에 해당하는 유저가 없음" }) } // 2. 요청된 이메일이 있다면 비밀번호 체크 user.comparePassword(req.body.password, (err,isMatch)=>{ if(!isMatch){ return res.json({ loginSuccess : false, massage : "비밀번호가 틀립니다" }) } // 3. 위 조건을 모두 만족하면 Token 생성 user.generateToken((err,user)=>{ if(err) return res.status(400).send(err) // 현재 user에는 토큰이 있음 토큰을 쿠키에 저장 res.cookie("x_auth",user.token).status(200).json({ loginSuccess : true, userID : user._id }) }) }) }) }) app.listen(port, () => { console.log(`Example app listening on port ${port}`) })
  6. // Model/User.js const jwt = require('jsonwebtoken'); userSchema.methods.generateToken = function(callbackfunk){ //jsonwebtoken을 이용하여 토큰 생성 var user = this; var token = jwt.sign(user._id.toHexString(), 'secretToken') // user._id + 'secretToken' = token // user.id + secretToken 을 이용하여 토큰을 생성하고 나중에 secretToken을 이용하여 user.id 확인 가능 user.token = token user.save(function(err, user){ if(err) return callbackfunk(err) callbackfunk(null, user) }) }
  7. npm install jsonwebtoken --save npm install cookie-parser --save
  8. JsonWebToken 라이브러리 설치

로그인 테스트

포스트맨을 이용하여 로그인 확인

  • 정보를 잘못 입력했을 때스크린샷 2022-12-28 오후 9 12 17
  • 정보를 제대로 입력했을 때스크린샷 2022-12-28 오후 9 13 16

제대로 나오는걸 확인할 수 있다.

'웹개발 > React' 카테고리의 다른 글

#9 Auth 기능 추가(ReactJS)  (0) 2023.01.08
#7 Bcrypt로 비밀번호 암호화(ReactJS)  (0) 2023.01.08
#6 비밀 설정 정보 관리(ReactJS)  (0) 2023.01.08