개발 노트

내가 사용한 JWT 본문

React

내가 사용한 JWT

알 수 없는 사용자 2023. 1. 30. 14:37

 

//로그인. 첫 로그인 버튼클릭
router.post('/login/IDPW', (req, res) => {
  const userId = req.body.userId;
  const userPw = req.body.userPw;
  db.query(
    `SELECT
    (SELECT devVal FROM dw_device_config WHERE devName='Farm_web_ID' LIMIT 1) farmWebId,
    (SELECT devVal FROM dw_device_config WHERE devName='Farm_Web_Code' LIMIT 1) farmCode`,
    (err, result) => {
      if (err) {
        log(err);
      } else {
        if (userId === result[0].farmWebId && userPw === result[0].farmCode) {
          const id = userId;
          const pw = userPw;
          const accessToken = jwt.sign({ id }, 'jwtSecret', {
            expiresIn: '1h',
          });
          const refreshToken = jwt.sign({ id }, 'jwtSecret', {
            expiresIn: '12h',
          });
          res.send({ result: 'SUCCESS', accessToken, refreshToken });
        } else {
          res.send({ result: 'FAIL' });
        }
      }
    },
  );
});

token값을 줄 때 sign으로 토큰을 정의하며 ({헤더값},내용(playload),옵션(파기시간))을 주는 식으로 간단하게 토큰을 만들어서 적용을 했다.

토큰을 사용함에 있어서 어려웠던 것은 미들웨어와 axios.interceptor이다.

const log = require('../../logger');
const router = require('express').Router();
const db = require('../../utils/db');
const fs = require('fs');

const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');

//로그인. 미들웨어
log('login');
exports.jwtMiddleware = async (req, res, next) => {
  try {
    //토큰 가져오기, 비밀번호 할당
    const token = req.headers.accesstoken;
    let jwt_secret = 'jwtSecret';
    //검증단계
    req.decoded = jwt.verify(token, jwt_secret);
    return next();
  } catch (err) {
    console.log('err :>> ', err);
    if (err.name == 'TokenExpiredError') {
      return res.status(403).json({ success: false, message: 'token 만료' });
    }
    return res
      .status(401)
      .json({ success: false, message: 'token이 유효하지 않습니다.' });
  }
};

위는 내가 만들어서 사용한 미들웨어인데 간단하게 jwt,verify로 인증하고 err를 체크하는 형식으로 진행했다.

 await request
      .post('login/IDPW', {
        userId: userId,
        userPw: userPw,
      })
      .then((res) => {
        const accessToken = res.data.accessToken;
        const refreshToken = res.data.refreshToken;
        localStorage.setItem(
          'user',
          JSON.stringify({ accessToken, refreshToken })
        );
        // API 요청하는 콜마다 헤더에 accessToken 담아 보내도록 설정
        request.interceptors.request.use(
          function (config) {
            const user = localStorage.getItem('user');
            if (!user) {
              config.headers['accessToken'] = null;
              config.headers['refreshToken'] = null;
              return config;
            }
            const { accessToken, refreshToken } = JSON.parse(user);
            config.headers['accessToken'] = accessToken;
            config.headers['refreshToken'] = refreshToken;
            return config;
          },
          function (error) {
            console.log(error);
            return Promise.reject(error);
          }
        );
        request.interceptors.response.use(
          (response) => {
            console.log('111', 111);
            return response;
          },
          async (error) => {
            console.log('2222 :>> ', 2222);
            if (error.response.request.status === 403) {
              try {
                console.log('error403 :>> ', error);
                const originalRequest = error.config;
                const data = await request.get('/login/refresh');
                console.log('data :>> ', data);
                if (data) {
                  const { accessToken, refreshToken } = data.data;
                  originalRequest.headers.accessToken = accessToken;
                  originalRequest.headers.refreshToken = refreshToken;
                  localStorage.removeItem('user');
                  localStorage.setItem(
                    'user',
                    JSON.stringify({ accessToken, refreshToken })
                  );
                  return await request.request(originalRequest);
                } else {
                  navigate('/Login');
                }
              } catch (error) {
                localStorage.removeItem('user');
                console.log(error);
                navigate('/Login');
              }
              return Promise.reject(error);
            }
            return Promise.reject(error);
          }
        );

        request.defaults.headers.common[
          'Authorization'
        ] = `Bearer ${accessToken}`;
      })
      .catch((error) => {
        console.log(error);
      });
    let preData = [];
    preData.push({ ID: userId });
    preData.push({ PW: userPw });
    let data = JSON.stringify(preData);
    message.success('통과');
    navigate('/');
    //똑같다면 포스트 아니라면 error ~~가 다릅니다.
  };

위의 코드는 인증을 진행하는 axios코드인데 requst가 axios라고 보면 된다.

로그인시에 인터셉터를 심어놔서 모든 미들웨어잡업시에 인터셉터가 일을 하게 된다. (처음 안 정보)

하지만 새로고침을 하면 로그인 버튼 클릭시에만 작동을 하게 짜놨는데 클릭을 안해서 인터셉터가 안 심어지는 바람에 버그가 일어났다. 

그래서 처음 시작할 때 최 상단 컴포넌트에서 인터셉터 response만 심어놓도록 작업을 해놓았는데 이게 좋은 방법일지는 의문이다.

 

오늘 찾은 블로그인데 참고해서 확실하게 공부를 해놔야겠다.

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-JWTjson-web-token-%EB%9E%80-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC