티스토리 뷰

Spring Security의 Security Session 기반의 인증 방식을 사용하여 로그인을 구현하려고 했지만, 프론트와 합치는 과정에서 Session이 전달되지 않는 오류가 발생했다. WithCridential 설정도 바꿔주고 서브도메인을 서버 IP와 연결시켜 cors 에러도 하나하나 해결하였지만 JWT로 구현하자는 의견이 많아 결국 JWT를 구현하게 되었다.

출처: https://velog.io/@dsunni/Spring-Boot-React-JWT%EB%A1%9C-%EA%B0%84%EB%8B%A8%ED%95%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0

일단 Spring과 React를 합친 프로젝트를 분석했당

 

SecurityContextHolder

Security Filter

HTTP 통신

왜 갑자기 HTTP에 대해서 나오는지 궁금할 수 있다.
"로그인" 이라는 과정은 서버와 클라이언트가 데이터를 주고 받는 통신 방법이 필요하다.

-> HTTP는 connectless/stateless 속성이 필요하다.

 

토큰 방식 (클라이언트 유지)

서버에 저장하지 않아서 서버에 확장성이 있다.
위에서 말했듯 로그인을 했을 때 해당 서버에만 요청을 보내는 것이 아닌
요청이 들어왔을 때 해당 토큰이 유효한지만 체크하면 되기 때문에
어떤 서버로 요청을 보내도 상관이 없다

 

JWT Secret Key

방법1

@value API 사용

  1. application.properties의 데이터를 불러올 클래스에 @Component를 붙여 Spring Bean으로 등록한다.
@Component
public class JwtTokenUtils {
  1. @Value 어노테이션에 application.properties에서 작성한 key를 인식시킨다.
@Value("{jwt.secret}")
public String jwtSecret;

방법2

Environment API 사용

  1. Environment를 @Autowired로 등록한다.
@Autowired
private Environment environment;
  1. getProperty() 메소드를 사용하여 porperties의 키값을 읽어온다.
environment.getProperty("jwt.secret")

JWT 와 Security 설정

  • JWT 관련
    • TokenProvider: 유저 정보로 JWT 토큰을 만들거나 토큰을 바탕으로 유저 정보를 가져옴
    • JwtFilter: Spring Request 앞단에 붙일 Custom Filter
  • Spring Security 관련
    • JwtSecurityConfig: JWT Filter 를 추가
    • JwtAccessDeniedHandler: 접근 권한 없을 때 403 에러
    • JwtAuthenticationEntryPoint: 인증 정보 없을 때 401 에러
    • SecurityConfig: 스프링 시큐리티에 필요한 설정
    • SecurityUtil: SecurityContext 에서 전역으로 유저 정보를 제공하는 유틸 클래스

등록된 (registered) 클레임

  • iss: 토큰 발급자 (issuer)
  • sub: 토큰 제목 (subject)
  • aud: 토큰 대상자 (audience)
  • exp: 토큰의 만료시간 (expiraton), 시간은 NumericDate 형식으로 되어있어야 하며 (예: 1480849147370) 언제나 현재 시간보다 이후로 설정되어있어야합니다.
  • nbf: Not Before 를 의미하며, 토큰의 활성 날짜와 비슷한 개념입니다. 여기에도 NumericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않습니다.
  • iat: 토큰이 발급된 시간 (issued at), 이 값을 사용하여 토큰의 age 가 얼마나 되었는지 판단 할 수 있습니다.
  • jti: JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용됩니다. 일회용 토큰에 사용하면 유용합니다.

Bearer Authentication란?

API에 접속하기 위해서는 access token을 API 서버에 제출해서 인증을 해야 합니다. 이 때 사용하는 인증 방법이 Bearer Authentication 입니다. 

 

 JWT의 구조라고 설명한 Header.Payload.Signature 구조는 JWS의 직렬화 방법 중 하나인 Compact Serialization 형식으로 직렬화한 것이다.

// Access Token 생성
Date accessTokenExpiresIn = new Date(now + ACCESS_TOKEN_EXPIRE_TIME);
String accessToken = Jwts.builder()
        .setSubject(authentication.getName())       // payload "sub": "name"
        .claim(AUTHORITIES_KEY, authorities)        // payload "auth": "ROLE_USER"
        .setExpiration(accessTokenExpiresIn)        // payload "exp": 1516239022 (예시)
        .signWith(key, SignatureAlgorithm.HS512)    // header "alg": "HS512"
        .compact();

Token을 직렬화하는 과정

 

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함