coding/Node.js

npm jsonwebtoken

JIN_Coder 2022. 7. 29. 00:57

전에도 js에서 ajax를 이용하여 JWT 토큰을 만들어 로그인을 시도하고 로그인정보를 확인하는 JWT에 다룬적이 있다.

이번엔 node에서 jsonwebtoken을 이용하여 토큰을 생성하여 로그인에 대해 알아보자

 

token 방식의 특징

- 사용자 정보를 일일히 서버의 세션에 저장하지 않고, 사용자의 로컬에 저장.

- 사용자가 요청을 보낼 때마다 유저 정보 확인을 일일히 하지 않아도 됨.

- 웹 표준 기반 기술로써, 여러 환경에서 지원

이러한 토큰 방식을 사용하기 위해서는 JWT(Json Web Token) 기술을 사용한다.

 

 

JWT 설치

npm i jsonwebtoken

 

토큰 생성 방법

const jwt = require('jsonwebtoken');

var userInfo = {id: 1, username: 'jin'};
var secretKey = 'testKey';
var options = {expiresIn: '7d', issuer: 'inyongTest', subject: 'userInfo'};

const token = jwt.sign(userInfo, secretKey, options, 
  function(err){
    if (err) {
      return console.log(err);
    };
  };
);
console.log(token); // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJpbnlvbmciLCJpYXQiOjE1NTc0ODc2MjIsImV4cCI6MTU1ODA5MjQyMiwiaXNzIjoiaW55b25nVGVzdCIsInN1YiI6InVzZXJJbmZvIn0.idVKe2FVsmvwYBPFJc9vMXi4eZRfFJ6rwhiHIY4gZeo

jwt.sign() 함수에 들어가는 4가지 인자

- userInfo : 아이디, 비밀번호 등 사용자 정보가 들어간 object이다. 형식은 상관없음.

- secretKey : 여러가지 복잡한 문자열로 되어있는 키.(보안 주의)

- options: 토큰에 대한 여러가지 정보를 설정한다.
expiresIn은 토큰 만료일,
issuer, subject는 토큰에 대한 정보. 외에도 options가 더 있다.

- 4번째 인자로 들어가는 익명함수 : token 생성결과를 4번째 인자의 콜백함수로 받을 수 있으므로 넣어준 함수.

 

예시)

클라에게 요청을 받아 토큰을 생성하여 클라에게 전달하는 응답

const jwt = require('jsonwebtoken');

router.post('/login', async (req, res) => {
  try {
    const { email, password } = req.body;

    const user = await User.findOne({ where: { email, password } });

    if (!user) {
      res.status(400).send({
        errorMessage: '이메일 또는 비밀번호가 맞지 않습니다.',
      });
      return;
    }
	
    // 토큰 생성(유저정보가 일치하여 토큰 생성)
    const token = jwt.sign({ userId: user.userId }, 'secretKey');
    res.send({ token });
  } catch (err) {
    console.log(err);
    res.status(400).send({
      errorMessage: '요청한 데이터 형식이 올바르지 않습니다.',
    });
  }
});

 

 

토큰 검증 방법

클라는 서버에게 토큰을 받은 후, 서버에게 요청을 보낼때 request.Header에 토큰을 포함하여 요청을 보냄

const secretKey = 'testKey'; // 아까 token 만들때 썼던 secretkey
const router = (req, res) => {
  const token = req.headers['x-access-token'] || req.query.token;
  jwt.verify(token, secretKey, 
    function(err, decoded){
      console.log(err) // 유효하지 않은 토큰
      console.log(decoded) // 유효한 토큰, 유저 정보 Object 반환
    }
}


// 토큰을 까서 시크릿 키로 유효한 것인지 확인
// const decoded = jwt.verify(token, "sparta")

// 토큰을 까서 정보를 보기만 가능(토큰이 유효한 것인지는 확인 안함)
// const decoded2 = jwt.decode(token)

jwt.verify() 함수에 들어가는 매개변수 3개

- token: client에게서 받은 token

- secretkey : token 생성 시 사용했던 secretKey

- 3번째 인자로 들어간 익명함수 : 유효성 검사 결과를 처리할 callback 함수

 

예시)

로그인 정보 확인

토큰의 유효성 검사를 하는 미들웨어를 만들어 로그인이 필요한 라우터에 미들웨어의 경로를 거치게 하여

사용자 정보가 확인되면 토큰에 들어있는 유저의 정보를 라우터에서서 활용 할수 있음

const jwt = require('jsonwebtoken');
const { User } = require('../models/index');

// 사용자 인증을 확인 할때 미들웨어로 만들어 로그인 이후 필요한 라우터에 미들웨의 경로를
// 거쳐 로그인 여부를 확인함

// 사용자 인증 미들웨어
module.exports = (req, res, next) => {
  const { authorization } = req.headers;
  const [tokenType, tokenValue] = authorization.split(' ');

  if (tokenType !== 'Bearer') {
    res.status(401).send({
      errMessage: '로그인 후 사용하세요.',
    });
    return;
  }

  // 토큰 유효성 검증
  try {
    const { userId } = jwt.verify(tokenValue, 'secretKey');
    User.findByPk(userId).then((user) => {
      res.locals.user = user;
      next();
    });
  } catch (error) {
    res.status(401).send({
      errMessage: '로그인 후 사용하세요.',
    });
    return;
  }
};
const authMiddleware = require('../middlewares/auth-middleware');

// 내 정보 조회(사용자 인증 미들웨어에서 인증된 값을 가져와서 로그인여부를 확인)
router.get('/users/me', authMiddleware, async (req, res) => {
  const { user } = res.locals;
  res.send({
    user: {
      email: user.email,
      nickname: user.nickname,
    },
  });
});

 

 

 

 

[2019.05.10] JWT-Token 방식의 정보 인증 [사용법]

사용자가 로그인 후, 유저 정보를 cookie,Session 방식이 아닌 token 방식으로 안전하게 관리하는 방법이 있다. # token 방식의 특징 사용자 정보를 일일히 서버의 세션에 저장하지 않고, 사용자의 로컬

helloinyong.tistory.com

 

'coding > Node.js' 카테고리의 다른 글

모듈(module), require(), IIFE  (0) 2022.08.03
sequelize CRUD 사용법  (0) 2022.08.02
package.json  (0) 2022.07.31
Express의 미들웨어  (0) 2022.07.23
Node.js, express  (0) 2022.07.22