Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- 자료구조
- 해시맵
- Mendix
- Recursion
- 재귀
- Sort
- 정렬
- MySQL
- 그래프
- algorithm
- 가중치없는그래프
- git
- 반효경교수님
- 매개변수 탐색
- lcap
- microflow
- 백트래킹
- domain model
- dfs
- 트리
- 멘딕스
- Bruteforce
- 프로그래머스
- SQL
- 이분탐색
- 완전탐색
- 자바
- 스택
- 집합
- 알고리즘
Archives
- Today
- Total
mondegreen
JWT 토큰 만들다 10시간 동안 경주마된 썰 본문
반응형
JWTUtils.java
package com.kkosunnae.deryeogage.global.util;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Date;
@Slf4j
@Component
public class JwtUtil {
@Value("${security.jwt.token.SK}")
private String SK;
@Value("${security.jwt.token.tokenValidTime}")
private long tokenValidTime;
// 토큰 생성
public String createToken(String claimId, Long data) throws UnsupportedEncodingException {
Date now = new Date();
SecretKey secretKey = Keys.hmacShaKeyFor(SK.getBytes(StandardCharsets.UTF_8));
String token = Jwts.builder()
//.setHeaderParam("enc", "HS256")
.setHeaderParam("typ","JWT")
.claim("userId", data)
.setIssuedAt(now)
.setExpiration(new Date(now.getTime()+tokenValidTime))
.signWith(secretKey, SignatureAlgorithm.HS256)
.compact();
return token;
}
// 토큰에서 회원 ID 추출
public Long getUserId(String token){
// 유효성 검사
try {
validateToken(token);
} catch (RuntimeException e) {
throw new RuntimeException("토큰에 문제가 있어요 Invalid token: " + e.getMessage());
}
//디코더 객체 생성
Base64.Decoder decoder = Base64.getDecoder();
//토큰에서 payload 추출
final String[] splitJwt = token.split("\\.");
//payload 디코딩
final String payLoadStr = new String(decoder.decode(splitJwt[1].getBytes()));
//디코딩된 문자열 JSON으로 변환
JsonParser parser = new JsonParser();
JsonObject jsonObject = parser.parse(payLoadStr).getAsJsonObject();
//사용자의 id를 반환
return jsonObject.get("userId").getAsLong();
}
// 유효성 검사
public void validateToken(String token) throws RuntimeException {
SecretKey secretKey = Keys.hmacShaKeyFor(SK.getBytes(StandardCharsets.UTF_8));
try {
Jwts.parserBuilder().setSigningKey(secretKey).build().parseClaimsJws(token);
} catch (ExpiredJwtException e) {
throw new RuntimeException("Expired JWT token: 토큰 만료");
} catch (UnsupportedJwtException e) {
throw new RuntimeException("Unsupported JWT token: 지원되지 않는 토큰");
} catch (MalformedJwtException e) {
throw new RuntimeException("Invalid JWT token: 유효하지 않은 토큰");
} catch (SignatureException e) {
throw new RuntimeException("Invalid JWT signature: 유효하지 않은 서명");
} catch (IllegalArgumentException e) {
throw new RuntimeException("JWT claims string is empty.: claims이 비어있음");
}
}
}
BoardController.java
public class BoardController {
private final JwtUtil jwtUtil;
private final BoardService boardService;
//글 작성 // Swagger테스트한다고 @requestBody 뺌
@PostMapping("/boards")
public Response<Object> saveBoard(@RequestHeader HttpHeaders header, @RequestBody BoardDto boardDto){
String token = header.getFirst("accessToken");
log.info("헤더에서 가져온 토큰 정보: "+ token);
Long userId = jwtUtil.getUserId(token);
boardDto.setUserId(userId);
log.info("userId :", boardDto.getUserId());
boardService.save(boardDto);
return Response.success(null);
}
}
위 코드가 성공한 코드이다..
10시간 동안 경주마처럼 JWTUtils.java에서만 오류 원인을 찾고 있었고 실제 원인은 헤더에서 토큰 값을 가져오는 과정에 있었다. GetMapping인 경우 header에서 키값을 기준으로 value를 찾아서 toString해주면 되었다.
하지만 Post Mapping은 달랐다.....(헝)
Spring Framework에서 HTTP 요청 헤더의 값을 가져오는 방식과 관련해 get 메소드는 HttpHeaders 객체에서 헤더의 값을 가져오지만, Post인 경우는 List<String> 타입을 반환한다. 따라서 toString() 메소드를 호출하면 token을 대괄호를 붙여서 가져오고.... 나의 유효성 검사는 끊임없이 서명 오류를 내었던 것이다... 헝...
따라서! toString대신 getFirst메서드를 활용해 첫번째 값을 가져오고 헤더값이 없는 경우 null을 반환한다..
고생했다 정말.
반응형
'기타 > 공통프로젝트_에러로그' 카테고리의 다른 글
GitLab MergeRequest 시 충돌 발생 -> Resolve locally 해결 (0) | 2023.08.08 |
---|---|
Your local changes to the following files would be overwritten by merge 오류 (0) | 2023.07.25 |
MySQL 사용자 및 데이터 베이스 생성 후 스프링 부트 프로젝트 연결(로컬) (0) | 2023.07.25 |
스프링 부트 프로젝트 실행했더니 로그인 하라고요? (0) | 2023.07.25 |
스프링 부트 프로젝트 시 의존성 주입 스코프 (0) | 2023.07.25 |