spring
[ Spring Boot 3 + Spring Security 6 + OAuth2.0 + JWT ] 마이그레이션과 같이 진행되는 OAuth2 로그인/회원가입 3
dev_popo
2023. 12. 22. 15:48
하던 플젝이랑 합친 거라 좀 어수선한데
Menu관련된 소스는 안봐도 됩니당. 로그인만 참고하세요
https://github.com/seulgi-i/authProject/tree/master
GitHub - seulgi-i/authProject
Contribute to seulgi-i/authProject development by creating an account on GitHub.
github.com
package com.oauth.clientserver.repository;
import com.oauth.clientserver.repository.entity.UserEntity;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<UserEntity, String> {
UserEntity findByEmail(String email);
}
package com.oauth.clientserver.service;
import com.oauth.clientserver.utils.JwtUtil;
import org.springframework.stereotype.Service;
@Service
public class UserService {
long tokenPeriod = 1000L * 60L * 10L;
long refreshTokenPeriod = 1000L * 60L * 60L * 24L * 7L; // 1 week
public String login(String userName) {
return JwtUtil.createJwt(userName, tokenPeriod);
}
public String refreshToken(String userName) {
return JwtUtil.createJwt(userName, refreshTokenPeriod);
}
}
package com.oauth.clientserver.service;
import com.oauth.clientserver.response.*;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class ResponseService {
public <T> SingleResponse<T> getSingleResponse (T data) {
SingleResponse singleResponse = new SingleResponse();
singleResponse.data = data;
setSuccessResponse(singleResponse);
return singleResponse;
}
public <T> ListResponse<T> getListResponse (List<T> dataList) {
ListResponse listResponse = new ListResponse();
listResponse.dataList = dataList;
setSuccessResponse(listResponse);
return listResponse;
}
public <T> MapResponse<T> getMapResponse (Map<T, T> body) {
MapResponse mapResponse = new MapResponse();
mapResponse.body = body;
setSuccessResponse(mapResponse);
return mapResponse;
}
public PostResponse postResponse () {
PostResponse postResponse = new PostResponse();
postResponse.body = true;
setSuccessResponse(postResponse);
return postResponse;
}
public PostResponse failResponse () {
PostResponse postResponse = new PostResponse();
postResponse.body = false;
setFailResponse(postResponse);
return postResponse;
}
public void setSuccessResponse (CommonResponse response) {
response.code = 200;
response.success = true;
response.message = "정상적으로 처리되었습니다.";
}
public void setFailResponse (CommonResponse response) {
response.code = 400;
response.message = "엥";
response.success = false;
}
}
package com.oauth.clientserver.utils;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import jakarta.annotation.PostConstruct;
import java.util.Base64;
import java.util.Date;
public class JwtUtil {
private static String secretKey = "my-token-secret-key";
@PostConstruct
protected void init() {
secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes());
}
public static String getUserName(String token, String secretKey) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token)
.getBody().get("userName", String.class);
}
public static boolean isExpired(String token, String secretKey) {
return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token)
.getBody().getExpiration().before(new Date());
}
public static String createJwt(String userName, Long expiredMs) {
return Jwts.builder()
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + expiredMs))
.signWith(SignatureAlgorithm.HS256, secretKey)
.claim("userName", userName).
compact();
}
}
package com.oauth.clientserver.config;
import com.oauth.clientserver.utils.JwtUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
import java.util.List;
@RequiredArgsConstructor
public class JwtFilter extends OncePerRequestFilter {
final String secretKey = "my-token-secret-key";
@Override
protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain)throws ServletException, IOException {
final String authorization = request.getHeader(HttpHeaders.AUTHORIZATION);
logger.error("authorization?.");
if (authorization == null || !authorization.startsWith("Bearer ")) {
logger.error("authorization 없습니다.");
filterChain.doFilter(request, response);
return;
}
//Token 꺼내기
String token = authorization.split(" ")[1];
logger.info("@@@@ token @@@ : " + token);
logger.info("@@@ secretKey @@@ :" + secretKey);
// Token Expired되어있는지 여부
if (JwtUtil.isExpired(token, secretKey)) {
logger.error("Token이 만료 되었습니다.");
filterChain.doFilter(request, response);
return;
}
//UserName Token에서 꺼내기
String userName = JwtUtil.getUserName(token, secretKey);
logger.info("userName");
logger.info(userName);
//권한부여
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(userName, null, List.of(new SimpleGrantedAuthority("USER")));
//Detail을 넣기
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
filterChain.doFilter(request, response);
}
}
package com.oauth.clientserver.controller.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Getter
public class LoginRequest {
@Schema(description = "사용자 이메일", example = "3213@ew.com")
private String email;
@Schema(description = "비밀번호", example = "1234")
private String password;
}
package com.oauth.clientserver.response;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.util.HashMap;
import java.util.Map;
@Setter
@Getter
public class LoginResponse extends CommonResponse {
private String accessToken;
private String refreshToken;
final Log logger = LogFactory.getLog(getClass());
public Map<String, String> loginSuccess (String accessToken, String refreshToken) {
this.accessToken = accessToken;
this.refreshToken = refreshToken;
return responseMap(accessToken, refreshToken);
}
public Map<String, String> responseMap (String accessToken, String refreshToken) {
Map<String, String> response = new HashMap<>();
response.put("accessToken", accessToken);
response.put("refreshToken", refreshToken);
logger.info("@@@@@ response @@@" + response);
return response;
}
}
package com.oauth.clientserver.response;
public class CommonResponse {
public boolean success;
public int code;
public String message;
}
이정도면...다 올린 거겠지..?
아무튼 대충..이렇게 했다~