네이버 로그인 API를 활용한 소셜로그인 구현 과정(with. Spring Security, JWT) - 4. JwtAuthenticationToken class 생성

Sia Hwang·2022년 11월 28일
0

인증 주체를 나타낼 JwtAuthenticationToken 클래스를 만들 것이다.

Location

package com.august.soil.api.security;
  • security 패키지 아래에 만든다.

AuthenticationRequest class

  • 시작하기에 앞서 인증 요청을 보낼 때 사용할 클래스를 만들 것이다.
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.builder.ToStringStyle;

import static org.apache.commons.lang3.builder.ToStringBuilder.*;

@Getter
@AllArgsConstructor
public class AuthenticationRequest {
  
  private String principal;
  
  private String credentials;
  
  protected AuthenticationRequest() {}
  
  @Override
  public String toString() {
    return reflectionToString(this, ToStringStyle.JSON_STYLE);
  }
}

JwtAuthenticationToken class

import lombok.Getter;
import org.springframework.security.authentication.AbstractAuthenticationToken;

@Getter
public class JwtAuthenticationToken extends AbstractAuthenticationToken {
  
  private final Object principal;
  
  private String credentials;
}
  • AbstractAuthenticationToken을 상속한 클래스를 생성한다.
  • 이 클래스는 인증 주체를 나타내는데, 그 정보는 principal 필드에 저장된다. 그런데 왜 모든 객체의 조상인 Object 타입일까?

그 이유는 로그인 전과 로그인 후의 인증 주체의 타입이 다르기 때문이다.
로그인 전에는 이메일 주소로만 인증과정을 진행할 것이기 때문에 String 타입이면 충분하지만, 로그인 후에는 이메일 주소 외에도 DB 테이블의 PK값, 사용자 이름 등의 추가 정보를 함께 저장할 필요가 생기고 그러기 위해 지난 포스트에서 만든 JwtAuthentication 타입 객체를 principal로 사용하게 된다.

  • getter도 만들어 준다.
import lombok.Getter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;

@Getter
public class JwtAuthenticationToken extends AbstractAuthenticationToken {
  
  ...
  
  // 로그인 전에 사용할 것
  public JwtAuthenticationToken(Object principal, String credentials) {
    super(null);
    super.setAuthenticated(false);
    
    this.principal = principal;
    this.credentials = credentials;
  }
  
  // 로그인 후에 사용할 것
  JwtAuthenticationToken(Object principal, String credentials, Collection<? extends GrantedAuthority> authorities) {
    super(authorities);
    super.setAuthenticated(true);
  
    this.principal = principal;
    this.credentials = credentials;
  }
}
  • 생성자를 만들자.
import lombok.Getter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;

@Getter
public class JwtAuthenticationToken extends AbstractAuthenticationToken {
  
  ...
  
  AuthenticationRequest authenticationRequest() {
    return new AuthenticationRequest(String.valueOf(principal), credentials);
  }
}
  • 인증 주체에 대한 정보를 받아 아까 만들었던 AuthenticationRequest를 생성하는 메서드를 작성한다.
import lombok.Getter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;

@Getter
public class JwtAuthenticationToken extends AbstractAuthenticationToken {
  
  ...
  
  public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
    if (isAuthenticated) {
      throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");
    }
    super.setAuthenticated(false);
  }
}
  • 인가자(Authority) 정보가 있는 생성자를 통해서만 인증 정보를 만들 수 있도록 제한해 주자.
import lombok.Getter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;
import org.apache.commons.lang3.builder.ToStringStyle;
import static org.apache.commons.lang3.builder.ToStringBuilder.reflectionToString;

@Getter
public class JwtAuthenticationToken extends AbstractAuthenticationToken {
  
  ...
  
  @Override
  public void eraseCredentials() {
    super.eraseCredentials();
    this.credentials = null;
  }
  
  @Override
  public String toString() {
    return reflectionToString(this, ToStringStyle.JSON_STYLE);
  }
}
  • 마지막으로 위 두 메서드를 오버라이딩 해 준다.

코드 전문 : https://github.com/miro7923/soil/blob/main/soil/src/main/java/com/august/soil/api/security/JwtAuthenticationToken.java

다음 포스트에서 계속...

profile
당면한 문제는 끝까지 해결하기 위해 노력하는 주니어 개발자입니다.

0개의 댓글