[내배캠] TIL, WIL/TIL

자바 스크립트

값싼외노자 2022. 12. 21. 11:32

로그인 기능 구현

app.js

const express = require("express");
const mongoose = require("mongoose");
mongoose.set('strictQuery', true);
const jwt = require('jsonwebtoken');

mongoose.connect("mongodb://127.0.0.1:27017/shopping-demo", {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});
const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));

const app = express();
const router = express.Router();

// 회원가입 기능 
const User = require('./models/user')
router.post('/users', async(req,res) => {
    const {nickname, email, password, confirmPassword} = req.body;

    // 1. 패스워드와 패스워드확인 값이 일치하는가
    // 2. 이메일과 닉네임 중복인가
    // 3. db에 삽입

    if (password !== confirmPassword) {
        res.status(400).json({errorMessage:"비밀번호 확인이 일치하지 않습니다."});
        return; // 위에 패스워드가 일치하지 않으면 밑에 코드를 더 실행하면 안되니까 여기서 리턴해준다
    }
    const existUser = await User.findOne({
        $or: [{email: email},{nickname:nickname}] // $or << 이안에 있는 값중에 하나라도 일치했을 때 보여준다.
    }); // 그리고 값중에 하나라도 일치한다는 뜻은 이메일이나 닉네임 중 중복이 있다는 뜻이기에 더 진행해선 안된다.
    
    if (existUser) {
        res.status(400).json({errorMessage:"이메일이나 닉네임이 중복됩니다."})
        return; // 중복되면 회원가입이 되면 안되기에 여기서 리턴하여 코드를 종료시킨다.
    }
    
    // 여기까지 위의 두 if문을 거치지 않았다면 회원가입이 정상적으로 실행되어야 한다.
    const user = new User({nickname,email,password});
    await user.save();
    
    res.status(201).json({}); // 스테이터스 201은 무언가를 만들었다는 creat 생성 코드! 기억하면 좋음
});

// 로그인 기능
router.post('/auth', async(req,res) => {
    const {email,password} = req.body;

    const user = await User.findOne({email}); // 특정 사용자를 이메일을 바탕으로 먼저 찾을 것 .
   
    // 1. 로그인이 가능하지 않을 경우를 먼저 구현하는데 우선 사용자가 존재하지 않거나
    // 2. 입력받은 패스워드와 사용자의 패스워드가 다를 때 에러 메세지를 발생 시켜야 한다.
   
    if (!user || password !== user.password) { 
        res.status(400).json({errorMessage:"로그인 정보가 일치하지 않습니다."})
        return;
    }

    // 이제는 위의 if문을 거치지 않는다면 사용자 정보가 일치한다는 뜻이니 로그인이 되어야한다. 

    const token = jwt.sign({userId:user.userId},'juho-secretkey') // 여기서 user.userId의 userId는 /models/user.js에서 8번줄인 _id값이란 뜻이다.
    // 즉, user.userId는 user._id와 같다는 뜻!

    res.status(200).json({
        "token":token,
    })
})

const authMiddleware = require('./middlewares/auth-middlewares');
router.get("/users/me", authMiddleware, async(req,res) => {
    res.json({user:res.locals.user}); // 내정보 조회api 기능
})

app.use("/api", express.urlencoded({ extended: false }), router); // urlencoded는 미들웨어, 즉 /api로 들어온것은 urlencoded 미들웨어를 거친다음 라우터로 가라 라는 뜻
app.use(express.static("assets")); // 정적 파일을 서빙해준다.

app.listen(8080, () => {
  console.log("서버가 요청을 받을 준비가 됐어요");
});

./middlewares/auth-middlewares.js

// 모델
// jwt
const User = require("../models/user");
const jwt = require("jsonwebtoken");

module.exports = async (req, res, next) => {
    const {authorization} = req.headers;
    const [authType, authToken] = authorization.split(" "); // Bearer와 실제 값이 띄어쓰기로 구분되어있기에 스플릿을 사용하여 나눠준다.
    // authType 에는 Bearer가 들어오고 
    // authToken 에는 실제 jwt값이 들어옴 
    console.log([authType,authToken]);

    if(authType !== "Bearer" || !authToken){
        res.status(400).json({
            errorMessage:"로그인 후 사용이 가능한 API입니다아아아아!!"
        });
        return;
    }


    try{ // try catch를 쓰는 이유가 시크릿키가 다르면 에러를 내뿜으면서 서버가 아예 닫혀버림
        // 복호화 및 검증
        const {userId} = jwt.verify(authToken,'juho-secretkey'); // 로그인할 때 쓰는 시크릿키로 검증
        console.log(userId);
        const user = await User.findById(userId);
        res.locals.user = user;
        console.log(user);
        next(); // 다음 미들웨어로 넘긴다.
    }catch(error){
        console.log(error);
        res.status(400).json({
            errorMessage:"로그인 후 사용이 가능한 API입니드아아앙!"
        })
        return;
    }
}

 

./models/user.js

const mongoose = require("mongoose");

const UserSchema = new mongoose.Schema({
  email: String,
  nickname: String,
  password: String,
});
UserSchema.virtual("userId").get(function () { // 가상으로 읽는 userId 파라미터가 추가된다
  return this._id.toHexString();
});
UserSchema.set("toJSON", {
  virtuals: true,
});
module.exports = mongoose.model("User", UserSchema);

'[내배캠] TIL, WIL > TIL' 카테고리의 다른 글

로그인 문제  (0) 2022.12.23
노드js  (0) 2022.12.22
자바 스크립트  (0) 2022.12.19
알고리즘  (0) 2022.12.19
자바 스크립트  (0) 2022.12.16