카카오계정 이 경로에서 동의하고 계속하기를 누르면 다시 카카오계정 이 화면으로 이동되서 동의하고 계속하기를 계속 나타냅니다.
@GetMapping("/auth/loginForm")
public String KakaoOauth(){
return "logintest/kakaoLogin";
}
@PostMapping("/auth/kakao/callback")
public String kakaoCallback(@RequestParam String code) {
OAuthLoginParams params = new KakaoLoginParams();
((KakaoLoginParams) params).setCode(code); // 이 부분을 추가하여 code 값을 설정
String accessToken = kakaoApiClient.requestAccessToken(params);
OAuthInfoResponse userInfo = kakaoApiClient.requestOauthInfo(accessToken);
return "카카오 로그인 처리 완료";
}
security Config부분
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(customizer → customizer.disable()) // CSRF 보호 비활성화
.authorizeRequests(authorizeRequests → {
authorizeRequests
.requestMatchers(new AntPathRequestMatcher(“/auth/kakao/callback”)).permitAll()
.requestMatchers(“/public/", "/login/”).permitAll() // 특정 경로에 대한 접근 허용
.anyRequest().authenticated(); // 다른 모든 요청은 인증 필요
})
// .formLogin(formLogincustomizer->formLogincustomizer // 로그인 페이지 및 로그인 처리 URL 설정
// .loginPage(“/login”) // 로그인 페이지 경로
// .loginProcessingUrl(“/perform_login”) // 로그인 처리 URL 경로
// .defaultSuccessUrl(“/dashboard”) // 로그인 성공 후 이동할 페이지
// .permitAll()) // 로그인 페이지는 누구나 접근 가능
// .logout(formLogoutcustomizer->formLogoutcustomizer // 로그아웃 설정
// .logoutUrl(“/perform_logout”) // 로그아웃 처리 URL 경로
// .logoutSuccessUrl(“/login”) // 로그아웃 성공 후 이동할 페이지
// .permitAll()); // 로그아웃 페이지는 누구나 접근 가능
.oauth2Login(
oauth2 → oauth2
// .loginPage(“/login”)
.authorizationEndpoint(authorizationEndpoint → {
authorizationEndpoint
.baseUri(“/oauth2/authorization”);
})
// .successHandler(oAuth2SuccessHandler())
.userInfoEndpoint(userInfo → userInfo.userService(oAuth2UserCustomService)
));
return http.build();
}
// .formLogin(formLogincustomizer->formLogincustomizer // 로그인 페이지 및 로그인 처리 URL 설정
// .loginPage(“/login”) // 로그인 페이지 경로
// .loginProcessingUrl(“/perform_login”) // 로그인 처리 URL 경로
// .defaultSuccessUrl(“/dashboard”) // 로그인 성공 후 이동할 페이지
// .permitAll()) // 로그인 페이지는 누구나 접근 가능
// .logout(formLogoutcustomizer->formLogoutcustomizer // 로그아웃 설정
// .logoutUrl(“/perform_logout”) // 로그아웃 처리 URL 경로
// .logoutSuccessUrl(“/login”) // 로그아웃 성공 후 이동할 페이지
// .permitAll()); // 로그아웃 페이지는 누구나 접근 가능
@Bean
public ClientRegistrationRepository clientRegistrationRepository(){
return new InMemoryClientRegistrationRepository(this.kakaoClientRegistration());
}
@Bean
public OAuth2AuthorizedClientRepository authorizedClientRepository(OAuth2AuthorizedClientService authorizedClientService){
return new AuthenticatedPrincipalOAuth2AuthorizedClientRepository(authorizedClientService);
}
private ClientRegistration kakaoClientRegistration(){
ClientRegistration.Builder builder=ClientRegistration.withRegistrationId("kakao");
builder.authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE);
builder.scope(new String[]{"profile_nickname","account_email"});
builder.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST);
builder.authorizationUri("https://kauth.kakao.com/oauth/authorize");
builder.redirectUri("http://localhost:8080/auth/kakao/callback");
builder.tokenUri("https://kauth.kakao.com/oauth/token");
builder.userInfoUri("https://kapi.kakao.com/v2/user/me");
builder.userNameAttributeName("id");
builder.clientName("Kakao");
builder.clientId("69445a05dee5a6928649b416c9df1964");
builder.clientSecret("hxEg8JGhjQm7Np8bMd18vQWZhVOjcPm0");
return builder.build();
}
SuccesHandler부분 설정입니다
public static final String REFRESH_TOKEN_COOKIE_NAME = "refresh_token";
public static final Duration REFRESH_TOKEN_DURATION = Duration.ofDays(14);
public static final Duration ACCESS_TOKEN_DURATION = Duration.ofDays(1);
public static final String REDIRECT_PATH = "auth/kakao/callback";
private final RefreshTokenRespository refreshTokenRepository;
private final MemberRepository memberRepository;
private final OAuth2AuthorizationRequestBasedOnCookieRepository authorizationRequestRepository;
private final UserService userService;
private final JwtTokenProvider jwtTokenProvider;
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
OAuth2User oAuth2User = (OAuth2User) authentication.getPrincipal();
User user = userService.findByEmail((String)oAuth2User.getAttributes().get("email"));
String subject = user.getMember().getEmail();
Date refreshTokenExpiry = new Date(System.currentTimeMillis()+REFRESH_TOKEN_DURATION.toMillis());
Date accessTokenExpiry = new Date(System.currentTimeMillis() + ACCESS_TOKEN_DURATION.toMillis());
String refreshToken=jwtTokenProvider.generate(subject,refreshTokenExpiry);
saveRefreshToken(user.getId(),refreshToken);
String accessToken = jwtTokenProvider.generate(subject,accessTokenExpiry);
String targetUrl = getTargetUrl(accessToken);
getRedirectStrategy().sendRedirect(request,response,targetUrl);
}
private void saveRefreshToken(Long memberId,String newRefreshToken){
Member member = memberRepository.findById(memberId).orElseThrow(()->new EntityNotFoundException("Member not found"));
RefreshToken refreshToken=refreshTokenRepository.findByMember(member)
.map(entity->entity.update(newRefreshToken))
.orElseGet(() -> new RefreshToken(member, newRefreshToken));
refreshTokenRepository.save(refreshToken);
}
//생성된 리프레시 토큰 쿠키에 저장
private void addRefreshTokneToCookie(HttpServletRequest request, HttpServletResponse response, String refreshToken){
int cookieMaxAge = (int)REFRESH_TOKEN_DURATION.toSeconds();
CookieUtil.deleteCookie(request,response,REFRESH_TOKEN_COOKIE_NAME);
CookieUtil.addCookie(response,REFRESH_TOKEN_COOKIE_NAME,refreshToken,cookieMaxAge);
}
//인증 요청과 관련된 속성 삭제
// private void clearAuthenticationAttributes(HttpServletRequest request,HttpServletResponse response){
// super.clearAuthenticationAttributes(request);
// authorizationRequestRepository.removeAuthorizationRequestCookies(request,response);
//
// }
//리다이렉트할 url 생성
private String getTargetUrl(String token){
return UriComponentsBuilder.fromUriString(REDIRECT_PATH)
.queryParam("token",token)
.build()
.toUriString();
}
}
현재 yml 설정입니다.
spring:
datasource:
url: jdbc:mysql://localhost:3306/foodtest?useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
username: root
password: mysql
driver-class-name: com.mysql.cj.jdbc.Driver
#spring:
datasource:
url: jdbc:mysql://awt??/db???useSSL=false&characterEncoding=UTF-8&serverTimezone=UTC
username: admin
password: admin1234
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
# 프로젝트 시작시 create로 두시고 진행중엔 none나 validate로 해주세요
properties:
hibernate:
show_sql: true
format_sql: true
default_batch_fetch_size: 100
# 페이징을 100개씩 해줍니다 해당 설정이 없다면 나중에 여러개 저장되어있는 db정보를 쿼리 1개씩 날림
database-platform: org.hibernate.dialect.MySQLDialect
oauth:
kakao:
client-id: 69445a05dee5a6928649b416c9df1964
client-secret: hxEg8JGhjQm7Np8bMd18vQWZhVOjcPm0
redirect-uri: http://localhost:8080/auth/kakao/callback
oauth-url: https://kauth.kakao.com
api-url: https://kapi.kakao.com
logging:
level:
org.hibernate.SQL: debug
org.hibernate.type: trace
recipeImgLocation: c:/recipe/images
server:
servlet:
encoding:
charset: UTF-8
jwt:
secret_key: