본문으로 바로가기

Passport JWT(JSON Web Token)

category Node, Nest, Deno/🔑 JWT, Passport.js 2020. 4. 25. 05:40
 

bcrypt와 JWT를 이용한 회원가입, 로그인, auth 미들웨어, 로그아웃

bcrypt A bcrypt library for NodeJS. www.npmjs.com jsonwebtoken JSON Web Token implementation (symmetric and asymmetric) www.npmjs.com 과거 다음과 같이 bcrypt를 이용해서 hash 처리를 해준 적이 있지만..

darrengwon.tistory.com

 

최근 작성한 포스트가 좀 더 간편하고 보안적이다.

 

 

 

passport-jwt

Passport authentication strategy using JSON Web Tokens

www.passportjs.org

 

mikenicholson/passport-jwt

Passport authentication using JSON Web Tokens. Contribute to mikenicholson/passport-jwt development by creating an account on GitHub.

github.com

 

jsonwebtoken

JSON Web Token implementation (symmetric and asymmetric)

www.npmjs.com

 

* graphql + apollo 환경에서 적용했습니다.

 

설치

 

JWT를 생성할 jsonwebtoken과 인증을 구현할 passport를 설치한다.

npm i passport passport-jwt
npm i jsonwebtoken

 

토큰 생성

import jwt from "jsonwebtoken";

// JWT 생성
export const generateToken = (id) => jwt.sign({ id }, process.env.JWT_SECRET);

 

JWT 기반 인증 구현

import passport from "passport";
import { Strategy, ExtractJwt } from "passport-jwt";

// 옵션
const jwtOptions = {
  jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
  secretOrKey: process.env.JWT_SECRET,
};

// 유저 인증. prisma를 통해 있는지 확인함
const verifyUser = async (payload, done) => {
  try {
    const user = await prisma.user({ id: payload.id });
    if (user !== null) {
      return done(null, user);
    } else {
      return done(null, false);
    }
  } catch (error) {
    return done(error, false);
  }
};

// authenticate 과정. 유저 정보를 req.user에 담자
export const authenticateJwt = (req, res, next) => {
  return passport.authenticate("jwt", { session: false }, (error, user) => {
    if (user) {
      req.user = user;
    }
    next();
  })(req, res, next);
};

// 앞서 정의한 옵션과 유저 인증을 사용하자.
passport.use(new Strategy(jwtOptions, verifyUser));

// passport 실행!
passport.initialize();

 

server에서 미들웨어로 passport 사용 및 context로 req 전달하기

import passport from "passport";
import "./passport";
import { authenticateJwt } from "./passport";

// GraphQLServer의 Context의 req에는 passport로 넘긴 값이 담겨있다.
const server = new GraphQLServer({
  schema,
  port: `${PORT}`,
  context: (req) => req,
});

// GraphQLServer에는 express가 내장되어 있다. 다음과 같이 접근할 수 있다.
server.express.use(logger("dev"));
server.express.use(authenticateJwt);

 

resolver에서 사용하기

 

GraphQLServer에 context로 req를 넘겨주었으므로 resolver에서 세번째 인자로 사용할 수 있다. 여기에 user 정보가 담겨 있다.

export default {
  Mutation: {
    requestSecret: async (_, args, req) => {
      console.log(req.request.user);
      
      ...(생략)
    },
  },
};

 

req.user를 꺼내보고 싶다면 HTTP 헤더에 Authorization을 붙여서 보내야 한다. 인자 앞에 Bearer를 붙여주는 것도 잊지 말자.

{"Authorization": "Bearer jwt토큰"}

 

req.user 출력 결과


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체