Files
hou27-jwt/src/main/java/com/api/jwt/JwtTokenProvider.java
2022-06-23 20:34:16 +09:00

143 lines
5.1 KiB
Java

package com.api.jwt;
import com.api.exception.CustomException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
// 유저 정보로 JWT 토큰을 만들거나 토큰을 바탕으로 유저 정보를 가져옴
@Component
public class JwtTokenProvider {
@Value("${jwt.token.access-token-secret-key}")
private String access_token_secret_key;
@Value("${jwt.token.refresh-token-secret-key}")
private String refresh_token_secret_key;
@Value("${jwt.token.access-token-expire-length}")
private long access_token_expire_time;
@Value("${jwt.token.refresh-token-expire-length}")
private long refresh_token_expire_time;
@Autowired
private UserDetailsService userDetailsService;
/**
* 적절한 설정을 통해 Access 토큰을 생성하여 반환
* @param authentication
* @return access token
*/
public String generateAccessToken(Authentication authentication) {
Claims claims = Jwts.claims().setSubject(authentication.getName());
// claims.put("auth", appUserRoles.stream().map(s -> new SimpleGrantedAuthority(s.getAuthority())).filter(Objects::nonNull).collect(Collectors.toList()));
Date now = new Date();
Date expiresIn = new Date(now.getTime() + access_token_expire_time);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(expiresIn)
.signWith(SignatureAlgorithm.HS256, access_token_secret_key)
.compact();
}
/**
* 적절한 설정을 통해 Refresh 토큰을 생성하여 반환
* @param authentication
* @return refresh token
*/
public String generateRefreshToken(Authentication authentication) {
Claims claims = Jwts.claims().setSubject(authentication.getName());
Date now = new Date();
Date expiresIn = new Date(now.getTime() + refresh_token_expire_time);
return Jwts.builder()
.setClaims(claims)
.setIssuedAt(now)
.setExpiration(expiresIn)
.signWith(SignatureAlgorithm.HS256, refresh_token_secret_key)
.compact();
}
/**
* Access 토큰으로부터 클레임을 만들고, 이를 통해 User 객체를 생성하여 Authentication 객체를 반환
* @param access_token
* @return
*/
public Authentication getAuthenticationByAccessToken(String access_token) {
String userPrincipal = Jwts.parser().setSigningKey(access_token_secret_key).parseClaimsJws(access_token).getBody().getSubject();
UserDetails userDetails = userDetailsService.loadUserByUsername(userPrincipal);
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
/**
* Refresh 토큰으로부터 클레임을 만들고, 이를 통해 User 객체를 생성하여 Authentication 객체를 반환
* @param refresh_token
* @return
*/
public Authentication getAuthenticationByRefreshToken(String refresh_token) {
String userPrincipal = Jwts.parser().setSigningKey(refresh_token_secret_key).parseClaimsJws(refresh_token).getBody().getSubject();
UserDetails userDetails = userDetailsService.loadUserByUsername(userPrincipal);
return new UsernamePasswordAuthenticationToken(userDetails, "", userDetails.getAuthorities());
}
/**
* http 헤더로부터 bearer 토큰을 가져옴.
* @param req
* @return
*/
public String resolveToken(HttpServletRequest req) {
String bearerToken = req.getHeader("Authorization");
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return null;
}
/**
* Access 토큰을 검증
* @param token
* @return
*/
public boolean validateAccessToken(String token) {
try {
Jwts.parser().setSigningKey(access_token_secret_key).parseClaimsJws(token);
return true;
} catch (JwtException e) {
// MalformedJwtException | ExpiredJwtException | IllegalArgumentException
throw new CustomException("Error on Access Token", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
/**
* Refresh 토큰을 검증
* @param token
* @return
*/
public boolean validateRefreshToken(String token) {
try {
Jwts.parser().setSigningKey(refresh_token_secret_key).parseClaimsJws(token);
return true;
} catch (JwtException e) {
// MalformedJwtException | ExpiredJwtException | IllegalArgumentException
throw new CustomException("Error on Refresh Token", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}