먼저 의존성 하나 추가한다.
implementation group: 'com.auth0', name: 'java-jwt', version: '4.3.0'이후 로그인 할 때 지금까지 사용한 sessionUser를 사용하지 않는다.
토큰
이 유저의 검증을 위해 JWT토큰을 발급한다.
토큰에는 보통 민감하지 않은, 유저를 구분할 수 있는 정보가 담긴 
엑세스토큰과
토큰 유효기간 갱신을 위한 리플레시토큰 두 가지를 발급한다.→ 엑세스토큰 털릴시 잠깐동안 해킹이 될 수는 있어도, 계속될 수는 없음. 
→ 만약 리플레시, 엑세스 토큰 둘 다 털리면 1개월 동안 계속털림
보안을 위해 여러가지 방법이 있음.
- 헤더에 디바이스 아이디, 아이피 등 오는데 이전 로그인 정보를 저장한 뒤 검증함.
- but 폰으로 햇다가 컴으로 할 수도 있고, 와이파이로 했다가 lte 이면 아이피가 바뀜
JWT 는
발급 시 원본과 해시값을 둘 다 가져간다.
검증할 때 시크릿도 발급함
머스태치 세팅을 제거한다.

서비스
  public User 로그인(UserRequest.LoginDTO loginDTO) {
        // 1. 해당 유저가 있는지 조회
        User user = userRepository.findByUsernameAndPassword(loginDTO.getUsername(), loginDTO.getPassword())
                .orElseThrow(() -> new Exception401("인증되지 않았습니다"));
        // 2. 조회가 되면 JWT만들고 응답
       // 비밀인부분, 털리면안대
        String accessToken = JwtUtil.create(user);
        return user;
    }컨트롤러
    @PostMapping("/login")
    public ResponseEntity<?> login(@Valid @RequestBody UserRequest.LoginDTO loginDTO, Errors errors) {
        User accessToken = userService.로그인(loginDTO);
        return ResponseEntity.ok()
                .header("Authorization", "Bearer"+accessToken)
                .body(Resp.ok(null));
    }
api 이기 때문에 리턴 타입 변경 및 매개변수 수정.
유틸
public class JwtUtil {
    public static String create(User user){
        String accessToken= JWT.create()
                .withSubject("바보")
                .withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7)) // 1주일
                .withClaim("id", user.getId()) // payload
                .sign(Algorithm.HMAC512("metacoding"));
        return accessToken;
    }
    // 검증 테스트
    public static User verify(String jwt){
        DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC512("metacoding")).build().verify(jwt);
        int id = decodedJWT.getClaim("id").asInt();
        String username = decodedJWT.getClaim("username").asString();
        return User.builder()
                .id(id)
                .username(username)
                .build();
    }
}테스트
   public void create_test(){
        User user = User.builder().id(1).username("ssar").build();
        String accessToken = JwtUtil.create(user);
        System.out.println(accessToken);
    }
    // eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiLrsJTrs7QiLCJpZCI6MSwiZXhwIjoxNzI3NDAxMDc4fQ.1Ajxs0WTdg40m1CNloFCty1adboo5FpE7qMS0-IfICKFO10xO0u_0dn5R-Cfb9kNdramh15HxGg4kyC7cadJfw
    @Test
    public void verify_test(){
        String accessToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiLrsJTrs7QiLCJpZCI6MSwiZXhwIjoxNzI3NDAxMDc4fQ.1Ajxs0WTdg40m1CNloFCty1adboo5FpE7qMS0-IfICKFO10xO0u_0dn5R-Cfb9kNdramh15HxGg4kyC7cadJfw";
        User user = JwtUtil.verify(accessToken);
        System.out.println(user.getId());
        System.out.println(user.getUsername());
    }

JWT의 전체 구조
최종적으로 JWT는 다음과 같이 세 부분을 마침표(.)로 연결한 문자열이다.
{Base64Url로 인코딩된 헤더}.{Base64Url로 인코딩된 페이로드}.{서명}
Share article