공부기록/Spring Security

[실습] 스프링 시큐리티 JWT 설정

jhs0129 2023. 1. 26. 14:48
320x100
반응형

목차

우선 JWT 사용 전에 왜 사용하는지에 대해 궁금하면 아래 사이트를 참고하면 좋을 듯 하다

JWT.io

[JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io](https://jwt.io/introduction)

JWT 사용

다음 오픈소스 라이브러리를 사용할 예정이다

https://github.com/auth0/java-jwt

[GitHub - auth0/java-jwt: Java implementation of JSON Web Token (JWT)

Java implementation of JSON Web Token (JWT). Contribute to auth0/java-jwt development by creating an account on GitHub.

github.com](https://github.com/auth0/java-jwt)

build.gradle

다음 의존성 추가

implementation 'com.auth0:java-jwt:4.2.1'

User refreshToken 추가

Entity

@Entity
public class User {
    //생략
    private String refreshToken;

    public void updateRefreshToken(String refreshToken) {
        this.refreshToken = refreshToken.replace("Bearer ", "");
    }
}

Repository

public interface UserRepository extends JpaRepository<User, Long> {
    //생략
    Optional<User> findUserByRefreshToken(String refreshToken);
}

Service

  • yml: 추후 값 사용시 이용될 것이다

application-jwt.yml

jwt:
  secret: asdf

  access:
    expiration: 20
    header: Authorization

  refresh:
    expiration: 30
    header: AuthorizationRefresh

application.yml

spring:
  profiles:
    include: jwt
public class JwtService {

    private final String PREFIX = "Bearer ";
    private final String BLANK = "";
    @Value("${jwt.secret}")
    private String secret;
    @Value("${jwt.access.expiration}")
    private long accessTokenValidationSeconds;
    @Value("${jwt.refresh.expiration}")
    private long refreshTokenValidationSeconds;
    @Value("${jwt.access.header}")
    private String accessHeader;
    @Value("${jwt.refresh.header}")
    private String refreshHeader;

    //토근 생성
    public String createAccessToken(String email) {
        return PREFIX.concat(JWT.create()
                .withSubject("AccessToken")
                .withExpiresAt(new Date(System.currentTimeMillis() + accessTokenValidationSeconds * 1000))
                .withClaim("email", email)
                .sign(Algorithm.HMAC512(secret)));
    }

    //토근 생성
    public String createRefreshToken() {
        return PREFIX.concat(JWT.create()
                .withSubject("RefreshToken")
                .withExpiresAt(new Date(System.currentTimeMillis() + refreshTokenValidationSeconds * 1000))
                .sign(Algorithm.HMAC512(secret)));
    }

    //response.header를 통해 token 전송
    public void sendBothToken(HttpServletResponse response, String accessToken, String refreshToken) {
        setAccessTokenInHeader(response, accessToken);
        setRefreshTokenInHeader(response, refreshToken);
    }

    public void setAccessTokenInHeader(HttpServletResponse response, String accessToken) {
        response.setHeader(accessHeader, accessToken);
    }

    public void setRefreshTokenInHeader(HttpServletResponse response, String refreshToken) {
        response.setHeader(refreshHeader, refreshToken);
    }

    //request.header를 통해 전달받은 토큰 추출
    public Optional<String> extractAccessToken(HttpServletRequest request) {
        return Optional.ofNullable(request.getHeader(accessHeader))
                .filter(refreshToken -> refreshToken.startsWith(PREFIX))
                .map(refreshToken -> refreshToken.replace(PREFIX, BLANK));
    }

    public Optional<String> extractRefreshToken(HttpServletRequest request) {
        return Optional.ofNullable(request.getHeader(refreshHeader))
                .filter(refreshToken -> refreshToken.startsWith(PREFIX))
                .map(refreshToken -> refreshToken.replace(PREFIX, BLANK));
    }

    //token에 포함된 값 확인
    public String extractUserEmail(String token) {
        return JWT.require(Algorithm.HMAC512(secret))
                .build()
                .verify(token.replace(PREFIX, BLANK))
                .getClaim("email")
                .asString();
    }

    //token 유효성 검사
    public boolean isTokenValid(String token) {
        try {
            JWT.require(Algorithm.HMAC512(secret))
                    .build()
                    .verify(token);
            return true;
        } catch (JWTVerificationException e) {
            return false;
        }
    }
}

위 코드들은 그렇게 이해하는데 어려움이 있지는 않을 것이다

해당 코드들을 작성을 했다면 JWT를 이용하는데 있어서 모든 베이스 준비가 완료되었다

이제 이것들을 활용하여 로그인 후 JWT 발급, 사이트 접근 시 권한 부여, Security 설정 변경 이 세가지만 작업하면 된다

320x100
반응형