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;
}

 

이정도면...다 올린 거겠지..?

아무튼 대충..이렇게 했다~