728x90
반응형
1. 의존성 추가
// jwt
implementation 'io.jsonwebtoken:jjwt:0.9.1'
2. JwtTokenManager
backend/auth/JwtTokenManager
package web.backend.auth;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Map;
import java.util.function.Function;
@Component
public class JwtTokenManager {
private static final String secret = "secretKey!!!";
// 토큰 유효 기간
public static final long JWT_TOKEN_VALIDITY = 60 * 60 * 24 * 1000L; //하루
/**
* 토큰 생성
*/
public String generateToken(String id, Map<String, Object> claims) {
return Jwts.builder()
.setClaims(claims) // 정보 저장
.setId(id)
.setIssuedAt(new Date(System.currentTimeMillis())) // 토큰 발행 시간 정보
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY)) // set Expire Time
.signWith(SignatureAlgorithm.HS512, secret)// 사용할 암호화 알고리즘과
// signature 에 들어갈 secret값 세팅
.compact();
}
/**
* 토큰 id 반환
*/
public String getTokenIdFromToken(String token) {
return getClaimFromToken(token, Claims::getId);
}
/**
* 토큰이 만료되었는지 Boolean 반환
*/
public Boolean isTokenExpired(String token) {
final Date expiration = getClaimFromToken(token, Claims::getExpiration);
return expiration.before(new Date());
}
/**
* 토큰 자체에 대한 정보 추출(id, expire 등)
*/
public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
final Claims claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token).getBody();// JWT payload 에 저장되는 정보단위
return claimsResolver.apply(claims);
}
/**
* 토큰 안의 모든 정보 추출
*/
public Claims getClaimsFromToken(String token) {
final Claims claims = Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token).getBody();// JWT payload 에 저장되는 정보단위
return claims;
}
}
3. Test
test/java/web/backend/auth/JwtTest
package web.backend.auth;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.*;
@Slf4j
public class JwtTest {
@Autowired
JwtTokenManager jwtTokenProvider = new JwtTokenManager();
Map<String, Object> map = new HashMap<>();
@BeforeEach
public void before() {
map.put("userId","teepo");
}
@Test
public void test() {
// 토큰 생성
String tokenString = jwtTokenProvider.generateToken("1", map);
log.info("tokenString={}",tokenString);
assertNotNull(tokenString);
// 토큰 Id
String tokenId = jwtTokenProvider.getTokenIdFromToken(tokenString);
log.info("tokenId={}", tokenId);
assertEquals("1",tokenId);
// 토큰이 만료되었는지
Boolean tokenExpired = jwtTokenProvider.isTokenExpired(tokenString);
log.info("tokenExpired={}",tokenExpired);
assertEquals(false, tokenExpired);
// 토큰 안의 모든 정보
Claims tokenClaims = jwtTokenProvider.getClaimsFromToken(tokenString);
log.info("tokenClaims={}", tokenClaims);
// before 메소드에서 생성한 데이터 조회
String value = tokenClaims.get("userId").toString();
log.info("userId={}",value);
assertEquals("teepo", value);
}
}
4. 로그 확인
이번엔 클라이언트한테 요청을 받고, 쿠키 안에 Token을 넣은 뒤 확인해보자. 코드는 전 포스트에서 이어진다.
1. Controller
backend/module/user/UserController
@PostMapping("/test")
public CommonResponse<String> jwtGenerateTest(HttpServletResponse response, @RequestBody User user) {
return new CommonResponse<String>(true, userService.jwtTest(response,user));
}
2. Service
backend/module/user/UserService
JwtTokenManager jwtTokenManager = new JwtTokenManager();
public String jwtTest(HttpServletResponse response ,User user) {
Map<String, Object> tokenMap = new HashMap<>();
tokenMap.put("userId", user.getUserId());
String tokenString = jwtTokenManager.generateToken("token1", tokenMap);
log.info("tokenValue={}",jwtTokenManager.getClaimsFromToken(tokenString));
Cookie cookie = new Cookie("token1",tokenString);
cookie.setMaxAge(86400000); // 하루
response.addCookie(cookie);
return "ok";
}
3. Postman
하단에 Cookies 버튼을 누르면 확인할 수 있다.
728x90
반응형
'Back-End > Spring Boot' 카테고리의 다른 글
Sping Boot | Backend Project | AWS S3 upload 구현 (0) | 2022.11.01 |
---|---|
Sping Boot | Backend Project | File Upload (0) | 2022.11.01 |
Sping Boot | Backend Project | Snake,Camel in Request, Response에 대한 고찰, 섞어서 쓰면 안되는 이유 ( with 사용자 설정 표기법 ) (0) | 2022.09.30 |
Sping Boot | Backend Project | Redis 적용하기 (1) | 2022.09.28 |
Sping Boot | Backend Project | RetryAspect (0) | 2022.09.28 |