Jwt를 이용한 회원가입, 로그인, 로그아웃

로그인에 대한 전략이 다양하게 있지만 크게 많이 사용되는 것은 세션/쿠키를 이용한 방법과 OAuth, 그리고 이번에 사용한 Jwt(Json Web Token)을 이용한 방법이 아닐까 싶다.

이 세 가지에 대한 내용은 그림으로 보는 것이 말로 설명한 것보다 이해가 빠르다.

바로 Jwt를 적용한 Spring Boot 프로젝트를 확인해보자.

제일 먼저 Build.gradle 파일에 jjwt를 적어준다.

    compile 'io.jsonwebtoken:jjwt-api:0.11.1'
    runtime 'io.jsonwebtoken:jjwt-impl:0.11.1',
            'io.jsonwebtoken:jjwt-jackson:0.11.1' // or 'io.jsonwebtoken:jjwt-gson:0.11.1' for gson

User Entity, Repository, Controller, Service를 작성해준다.

JwtService를 작성 해준다.

@Slf4j
@Service
public class JwtService {

  private static final String secretKey = "!122edasdji32irj23rjp2qwasdasdasdasd@!@@@!@#@$(&$#(&*(!#@&(*@&#(*@&$(*@&(*$&@(*$&(*#&$(*&(*&@(*&#(*@$&(*#&$@#@#^^&#^$#&$^#$#&@^#&*@#^@&#*@$@dposadjlkasjdlaj@!";
  private byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(secretKey);
  private SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
  private final Key KEY = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());


  public <T> String create(String key, T data, String subject) {
    String jwt = Jwts.builder()
        .setHeaderParam("typ", "JWT")
        .setHeaderParam("regDate", System.currentTimeMillis())
        //1000 * 60 * 60 * 24 = 1일
        //유효기간 1일
        .setExpiration(new Date(System.currentTimeMillis() + 1 * (1000 * 60 * 60 * 24)))
        .setSubject(subject)
        .claim(key, data)
        .signWith(KEY, this.signatureAlgorithm)
        .compact();

    return jwt;
  }

  public Boolean getExpToken(String jwt) {
    try {
      Date expiration = Jwts.parserBuilder().setSigningKey(KEY).build().parseClaimsJws(jwt)
          .getBody().getExpiration();
      Date now = new Date();

      if (expiration.after(now)) {
        return true;
      }
      return false;
    } catch (Exception e) {
      return false;
    }
  }

  public String getUserEmail(String jwt) {
    try {
      return String.valueOf(
          Jwts.parserBuilder().setSigningKey(KEY).build().parseClaimsJws(jwt).getBody()
              .get("userName"));
    } catch (Exception e) {
      return null;
    }
  }
}

JwtInterceptor를 작성해준다.

@RequiredArgsConstructor
@Component
public class JwtInterceptor implements HandlerInterceptor {

  private static final String HEADER_AUTH = "authorization";
  private final JwtService jwtService;


  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
    final String token = request.getHeader(HEADER_AUTH);
    if(token != null && jwtService.getExpToken(token)){
      request.setAttribute("userName", jwtService.getUserEmail(token));
      return true;
    }else{
      throw new Exception();
    }
  }
}

WebConfig 파일을 작성 후에 JwtInterceptor를 등록해준다.

@RequiredArgsConstructor
@Configuration
public class WebConfig implements WebMvcConfigurer {

  private static final String[] EXCLUDE_PATHS = {
      "/user/**",
      "/error/**"
  };

  private final JwtInterceptor jwtInterceptor;


  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(jwtInterceptor).addPathPatterns("/**")
        .excludePathPatterns(EXCLUDE_PATHS);

  }
}
  • 더 생각해 볼 사항

권한, 만료시에 연장을 어떤식으로? (갑자기 로그인 다시?)


© 2021. All rights reserved.

Powered by Hydejack v7.5.2