문의 시, 사용하시는 개발환경과 디벨로퍼스 앱ID를 알려주세요.
______현재 스프링부트 3.x 버전과 리액트 8.x 버전으로 작업중입니다.
ID: 1021973
백에서 값을 리액트로 넘겨주는 부분입니다.
@RestController
@Slf4j
@RequestMapping(“/public”)
public class OauthController {
private final OAuthLoginService oAuthLoginService;
private final KakaoApiClient kakaoApiClient;
private final AuthTokensGenerator authTokensGenerator;
private final MemberService memberService;
public OauthController(OAuthLoginService oAuthLoginService, KakaoApiClient kakaoApiClient, AuthTokensGenerator authTokensGenerator, MemberService memberService) {
this.kakaoApiClient = kakaoApiClient;
this.oAuthLoginService = oAuthLoginService;
this.authTokensGenerator = authTokensGenerator;
this.memberService = memberService;
}
@GetMapping("/auth/kakao/login")
public void KakaoOauthTest(HttpServletResponse response) throws IOException {
response.sendRedirect(kakaoApiClient.getAuthorizeUrl());
}
@GetMapping("/auth/kakao/callback")
public ResponseEntity<Map<String, Object>> kakaoCallback(@RequestParam("code") String code) {
KakaoLoginParams kakaoLoginParams = new KakaoLoginParams();
log.info("KakaoParams : {}", kakaoLoginParams);
//로그는 (+) 쓰지말고 아래처럼 "" 안에는 {} 로 변수 위치 잡아주고 (,) 뒤에다가 해당 위치에 넣을 변수 지정해주면 됨
log.info("code : {}", code);
kakaoLoginParams.setAuthorizationCode(code);
//카카오로부터 액세스 토큰 요청
String accessToken = kakaoApiClient.requestAccessToken(kakaoLoginParams);
//카카오로부터 사용자 정보 요청
OAuthInfoResponse userInfo = kakaoApiClient.requestOauthInfo(accessToken);
log.info("{}", userInfo.getEmail());
//DB에 User정보 담기
Long userId = oAuthLoginService.findOrCreateMember(userInfo);
//jwt 토큰 생성
AuthTokens jwtToken = authTokensGenerator.generate(userId);
Map<String, Object> responseBody = new HashMap<>();
responseBody.put("accessToken", accessToken);
responseBody.put("userInfo", userInfo);
responseBody.put("jwtToken",jwtToken.getAccessToken());
responseBody.put("success", true);
// 여기서 리다이렉트 하지말고 토큰 값이랑 프론트에서 필요한 사용자 정보를 보내주면 됨
return ResponseEntity.ok(responseBody);
}
@GetMapping("/redirect")
public ResponseEntity<Void> performRedirection(@RequestParam String redirectUrl) {
// 리디렉션을 수행하는 302 응답 생성
HttpHeaders headers = new HttpHeaders();
headers.add("Location", redirectUrl);
return new ResponseEntity<>(headers, HttpStatus.FOUND); // HttpStatus.FOUND: 302 응답 코드
}
프론트에서 처리하는 부분입니다.
import React from ‘react’;
import axios from ‘axios’;
import { useNavigate } from ‘react-router-dom’;
function LoginHandler() {
const navigate = useNavigate();
const handleKakaoLogin = async () => {
try {
const code = new URL(window.location.href).searchParams.get(‘code’);
const backendUrl = ‘http://localhost:8080’;
//카카오 인증 코드 전달
const res = await axios.get(`${backendUrl}/public/auth/kakao/callback`, {
params: { code }
});
if (res.status === 200) {
// JWT 토큰 저장 및 사용자 정보 처리
localStorage.setItem('jwtToken', res.data.jwtToken);
localStorage.setItem('userInfo', JSON.stringify(res.data.userInfo));
navigate('/boardlist');
} else {
console.error('로그인 실패');
}
} catch (error) {
console.error('로그인 에러', error);
// 에러 처리 로직
}
};
React.useEffect(()=>{
handleKakaoLogin();
},[]);
return(
<div className="LoginHandler">
<div className="notice">
<p>로그인 처리 중...</p>
</div>
</div>
);
}
yml 파일 설정입니다.
oauth:
kakao:
authorization-grant-type: authorization_code
client-id: 69445a05dee5a6928649b416c9df1964
client-secret: hxEg8JGhjQm7Np8bMd18vQWZhVOjcPm0
# redirect-uri: http://localhost:8080/oauth2/authorization/kakao
redirect-uri: http://localhost:8080/public/auth/kakao/callback
client-authentication-method: POST
client-name: kakao
oauth-url: https://kauth.kakao.com
api-url: https://kapi.kakao.com
scope:
- profile_nickname
- account_email
이런 식으로 redirect uri를 8080으로 설정했습니다.
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(customizer → customizer.disable()) // CSRF 보호 비활성화
.authorizeRequests(authorizeRequests → {
authorizeRequests
// .requestMatchers(new AntPathRequestMatcher(“/oauth2/authorization/kakao”)).permitAll()
.requestMatchers(
“/public/"
, "/BoardList/”
, “/login/"
, "/auth/”
,“/survey/"
, “/favicon.ico”
, “/error”
,"/api/”
,“/images/"
,"/recipe/”
,“/css/"
,"/js/”
).permitAll() // 특정 경로에 대한 접근 허용
.anyRequest().authenticated(); // 다른 모든 요청은 인증 필요
})
.httpBasic(Customizer.withDefaults())
.addFilterBefore(tokenAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
.sessionManagement((sessionManagement)->
sessionManagement.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED))
.formLogin(formLogincustomizer → formLogincustomizer // 로그인 페이지 및 로그인 처리 URL 설정
.loginPage(“/login”))// 로그인 페이지 경로
.oauth2Login(
oauth2 → oauth2
.loginPage(“/login”)
.authorizationEndpoint(authorizationEndpoint -> {
authorizationEndpoint
.baseUri("/oauth2/authorization")
.authorizationRequestRepository(oAuth2AuthorizationRequestBasedOnCookieRepository());
})
.redirectionEndpoint(redirection->redirection.baseUri("/oauth2/authorization/kakao")
)
.successHandler(oAuth2SuccessHandler())
).cors(Customizer.withDefaults());
return http.build();
}
security filter 설정인데요
http://localhost:8080/public/auth/kakao/callback?code=O3tmhBk8pUvLlJ9idcYelxn-KdJiIwelnaLKnDGPC5RRPDoTutvkQ5Z_-K4KKiVOAAABjXePzTsWphHJzwXJqw
이 부분에서 다음으로 넘어가질 않습니다.