logout 프로세서

이동현·2023년 4월 24일
0

코드 캠프 블로그

목록 보기
33/50

jwt와 Redis를 이용한 logout프로세서

logout api를 만든다.

// auth.service.ts
  async logout({ context }) {
    const accessToken = context.req.headers.authorization.replace(
      'Bearer ',
      '',
    );

    const refreshToken = context.req.headers.cookie.replace(
      'refreshToken=',
      '',
    );

    // console.log(accessToken, '과', refreshToken);

    try {
      const accessVerify = jwt.verify(
        accessToken, //
        process.env.JWT_ACCESS_KEY,
      ) as JwtPayload;
      const refreshVerify = jwt.verify(
        refreshToken,
        process.env.JWT_REFRESH_KEY,
      ) as JwtPayload;

      const accessTtl = accessVerify.exp - accessVerify.iat;
      const refreshTtl = refreshVerify.exp - refreshVerify.iat;

      // console.log(accessTtl, refreshTtl);
      // console.log(refreshVerify, accessVerify);
      // console.log(accessVerify.iat);

      // 캐쉬등록하기
      await this.cacheManager.set(`accessToken:${accessToken}`, accessToken, {
        ttl: accessTtl,
      });
      await this.cacheManager.set(
        `refreshToken:${refreshToken}`,
        refreshToken,
        {
          ttl: refreshTtl,
        },
      );

      return '로그아웃에 성공하였습니다!!';
    } catch (error) {
      throw new UnauthorizedException();
    }
  }

import { JwtPayload } from 'jsonwebtoken';를 쓰지 않으면 payload형식을 불러올수 없으니 주의!!!

// auth.resolver.ts
 @Mutation(() => String)
  async logout(
    @Context() context: IContext, //
  ) {
    return this.authService.logout({ context });
  }

validate에서 redis를 통해 로그아웃한 토큰인지 아닌지 확인해보기

// jwt-access.strategy.ts
async validate(req, payload) {
    //redis를 통해 로그아웃한 토큰인지 아닌지 확인해보기
    const accessToken = req.headers.authorization.replace('Bearer ', '');
    const redisAccessToken = await this.cacheManager.get(
      `accessToken:${accessToken}`,
    );

    // console.log(redisAccessToken);
    // console.log(accessToken);
    //성공시 로직 처리
    // console.log(req, payload); // { sub: qqwljlwqjlasd(유저ID)}
    if (accessToken === redisAccessToken) {
      throw new UnauthorizedException();
    }
    return {
      id: payload.sub,
    };
  }
//jwt-access.strategy.ts
  async validate(req, payload) {
    //성공시 로직 처리
    // console.log(payload); // { sub: qqwljlwqjlasd(유저ID)}
    const refreshToken = req.headers.cookie.replace('refreshToken=', '');
    const redisRefreshToken = await this.cacheManager.get(
      `refreshToken:${refreshToken}`,
    );

    // console.log(refreshToken, '=================', redisRefreshToken);
    if (refreshToken === redisRefreshToken) {
      throw new UnauthorizedException();
    }
    return {
      id: payload.sub,
    };
  }

passReqToCallback: true 윗부분 constructor에 적어주지 않으면 req를 받을 수 없다!
passReqToCallback이라는 옵션은 인증을 수행하는 인증 함수로 HTTP request를 그대로 전달할지 여부를 결정하기 때문이다!!

0개의 댓글