Skip to content

Commit

Permalink
fix: 무한 리다이렉트 오류 해결 (#7)
Browse files Browse the repository at this point in the history
UsernamePasswordAuthenticationToken을 직접 생성하지 않고,CustomOAuth2UserService의 loadUser메서가 OAuth2User를 구현한 CustomOauth2User를 반환하여 자동으로 OAuth2AuthenticationToken가 생성되도록 설정하여 오류 해결
  • Loading branch information
toychip committed Nov 29, 2023
1 parent f2be95d commit 903c026
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ public class Member extends BaseEntity {
private String gitLoginId;
private String gitEmail;
private String gitName;
private String profileImageUrl;

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
import lombok.Builder;

@Builder
public record AuthResponse(Long memberId, String gitLoginId, String gitProfileImageUrl) {
public record AuthResponse(Long memberId, String gitLoginId, String mail, String gitProfileImageUrl) {
}
13 changes: 8 additions & 5 deletions src/main/java/com/api/TaveShot/global/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.api.TaveShot.global.jwt.JwtAuthenticationFilter;
import com.api.TaveShot.global.oauth2.CustomOAuth2UserService;
import com.api.TaveShot.global.oauth2.CustomOAuthSuccessHandler;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
Expand All @@ -22,6 +23,7 @@ public class SecurityConfig {

private final CustomOAuth2UserService customOAuth2UserService;
private final JwtAuthenticationFilter jwtAuthenticationFilter;
private final CustomOAuthSuccessHandler customOAuthSuccessHandler;

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
Expand All @@ -47,18 +49,19 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
, "/api-docs/swagger-config"
, "/members/login"
,"/oauth/**"
,"/favicon.ico"
,"/login/**"
// , "/**"
).permitAll()
.anyRequest().authenticated());
http
.oauth2Login()
.authorizationEndpoint().baseUri("/oauth/authorize")
.and()
.redirectionEndpoint().baseUri("/login/oauth2/github/code")
.and()
.authorizationEndpoint().baseUri("/login/oauth2/code/github")
.and()
.userInfoEndpoint()
.userService(customOAuth2UserService);
.userService(customOAuth2UserService)
.and()
.successHandler(customOAuthSuccessHandler);
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);

return http.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ private OauthConstant() {
}

public static final String ID_PATTERN = "id";
public static final String AVATAR_URL_PATTERN = "avatar_url";
public static final String PROFILE_IMAGE_URL_PATTERN = "avatar_url";
public static final String LOGIN_PATTERN = "login";
// ToDo 추후 Github에서 제공하는 Name 을 사용할지 결정
public static final String NAME_PATTERN = "name";
public static final String EMAIL_PATTERN = "email";
public static final long ACCESS_TOKEN_VALID_TIME = 15 * 60 * 1000L;
Expand Down
21 changes: 3 additions & 18 deletions src/main/java/com/api/TaveShot/global/jwt/JwtProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,18 @@

import static com.api.TaveShot.global.constant.OauthConstant.ACCESS_TOKEN_VALID_TIME;

import com.api.TaveShot.domain.Member.domain.Member;
import com.api.TaveShot.domain.Member.repository.MemberRepository;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import javax.crypto.SecretKey;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

@Component
Expand Down Expand Up @@ -79,25 +75,14 @@ public void isValidToken(final String jwtToken) {
public void getAuthenticationFromToken(final String jwtToken) {

log.info("-------------- getAuthenticationFromToken jwt token: " + jwtToken);
String gitName = getGitName(jwtToken);
registerAuthentication(jwtToken, gitName);
getGitLoginId(jwtToken);

}

// token 으로부터 유저 정보 확인
private String getGitName(final String jwtToken) {
private void getGitLoginId(final String jwtToken) {
Long userId = Long.valueOf(getUserIdFromToken(jwtToken));
Member findMember = memberRepository.findById(userId).orElseThrow(() -> new RuntimeException("token 으로 Member를 찾을 수 없음"));
return findMember.getGitName();
}

private void registerAuthentication(final String jwtToken, final String gitName) {
// JWT 토큰이 유효하면, 사용자 정보를 연결 세션에 추가
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(gitName, jwtToken, new ArrayList<>());

// SecurityContextHolder 유저 등록
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
memberRepository.findById(userId).orElseThrow(() -> new RuntimeException("token 으로 Member를 찾을 수 없음"));
}

// 토큰에서 유저 아이디 얻기
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import static com.api.TaveShot.global.constant.OauthConstant.EMAIL_PATTERN;
import static com.api.TaveShot.global.constant.OauthConstant.ID_PATTERN;
import static com.api.TaveShot.global.constant.OauthConstant.LOGIN_PATTERN;
import static com.api.TaveShot.global.constant.OauthConstant.NAME_PATTERN;
import static com.api.TaveShot.global.constant.OauthConstant.PROFILE_IMAGE_URL_PATTERN;

import com.api.TaveShot.domain.Member.domain.Member;
import com.api.TaveShot.domain.Member.repository.MemberRepository;
Expand Down Expand Up @@ -37,27 +37,27 @@ private Member processOAuthUser(final Map<String, Object> userInfo) {
String gitLoginId = (String) userInfo.get(LOGIN_PATTERN);
Long gitId = ((Integer) userInfo.get(ID_PATTERN)).longValue();
String gitEmail = (String) userInfo.get(EMAIL_PATTERN);
String gitName = (String) userInfo.get(NAME_PATTERN);
String profileImageUrl = (String) userInfo.get(PROFILE_IMAGE_URL_PATTERN);

return memberRepository.findByGitId(gitId)
.orElseGet(() -> registerNewMember(gitId, gitLoginId, gitEmail, gitName));
.orElseGet(() -> registerNewMember(gitId, gitLoginId, gitEmail, profileImageUrl));
}

private Member registerNewMember(final Long gitId, final String gitLoginId,
final String gitEmail, final String gitName) {
final String gitEmail, final String profileImageUrl) {
Member newMember = Member.builder()
.gitId(gitId)
.gitLoginId(gitLoginId)
.gitEmail(gitEmail)
.gitName(gitName)
.profileImageUrl(profileImageUrl)
.build();

return memberRepository.save(newMember);
}

private CustomOauth2User createCustomOauth2User(final Member member, final Map<String, Object> userInfo) {

GithubUserInfo githubUserInfo = generateGithubInfo(userInfo);

return CustomOauth2User.builder()
.member(member)
.githubUserInfo(githubUserInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,29 @@ public class CustomOAuthSuccessHandler extends SimpleUrlAuthenticationSuccessHan
@Override
public void onAuthenticationSuccess(final HttpServletRequest request, final HttpServletResponse response,
final Authentication authentication) throws IOException {

CustomOauth2User oauth2User = (CustomOauth2User) authentication.getPrincipal();
GithubUserInfo githubUserInfo = createGitHubUserInfo(oauth2User);

if(response.isCommitted()) {
log.debug("------------------ Response 전송 완료");
}

String profileImageUrl = githubUserInfo.getProfileImageUrl();
String loginId = githubUserInfo.getLoginId();
Long gitId = githubUserInfo.getId();

log.info("------------------ "
+ "소셜 로그인 성공: " + loginId
+ "프로필 이미지: " + profileImageUrl);
log.info("------------------ 소셜 로그인 성공: " + loginId);

Integer id = githubUserInfo.getId();
String mail = githubUserInfo.getMail();
String profileImageUrl = githubUserInfo.getProfileImageUrl();

Member loginMember = memberRepository.findByGitId(gitId).orElseThrow(() -> new RuntimeException("해당 gitId로 회원을 찾을 수 없음"));
Member loginMember = memberRepository.findByGitId(Long.valueOf(id)).orElseThrow(() -> new RuntimeException("해당 gitId로 회원을 찾을 수 없음"));
String loginMemberId = String.valueOf(loginMember.getId());

registerHeaderToken(response, loginMemberId);

AuthResponse authResponse = AuthResponse.builder()
.memberId(loginMember.getId())
.mail(mail)
.gitLoginId(loginId)
.gitProfileImageUrl(profileImageUrl)
.build();
Expand All @@ -61,12 +61,6 @@ public void onAuthenticationSuccess(final HttpServletRequest request, final Http
registerResponse(response, authResponse);
}

private void registerHeaderToken(final HttpServletResponse response, final String loginMemberId) {
String ourToken = jwtProvider.generateJwtToken(loginMemberId);
// 어세스 토큰은 헤더에 담아서 응답으로 보냄
response.setHeader("Authorization", ourToken);
}

private GithubUserInfo createGitHubUserInfo(final CustomOauth2User oauth2User) {
Map<String, Object> userInfo = oauth2User.getAttributes();

Expand All @@ -75,16 +69,26 @@ private GithubUserInfo createGitHubUserInfo(final CustomOauth2User oauth2User) {
.build();
}

private void registerHeaderToken(final HttpServletResponse response, final String loginMemberId) {
String ourToken = jwtProvider.generateJwtToken(loginMemberId);
// 어세스 토큰은 헤더에 담아서 응답으로 보냄
response.setHeader("Authorization", ourToken);
}

private void registerResponse(final HttpServletResponse response,
final AuthResponse authResponse) throws IOException {
String encodedMemberId = URLEncoder.encode(String.valueOf(authResponse.memberId()), StandardCharsets.UTF_8);
String encodedLoginId = URLEncoder.encode(authResponse.gitLoginId(), StandardCharsets.UTF_8);
String encodedGitProfileImageUrl = URLEncoder.encode(authResponse.gitProfileImageUrl(), StandardCharsets.UTF_8);
// String encodedGitProfileImageUrl = URLEncoder.encode(authResponse.gitProfileImageUrl(), StandardCharsets.UTF_8);

// 프론트엔드 페이지로 토큰과 함께 리다이렉트
String frontendRedirectUrl = String.format(
"%s/oauth2/github/code?memberId=%s&gitLoginId=%s&profileImgUrl=%s",
REDIRECT_URL, encodedMemberId, encodedLoginId, encodedGitProfileImageUrl);
"%s/oauth2/github/code?memberId=%s&gitLoginId=%s"
// + "&profileImgUrl=%s"
,
REDIRECT_URL, encodedMemberId, encodedLoginId
// , encodedGitProfileImageUrl
);

response.sendRedirect(frontendRedirectUrl);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ public Collection<? extends GrantedAuthority> getAuthorities() {

@Override
public String getName() {
return member.getGitName();
return member.getGitLoginId();
}
}
16 changes: 6 additions & 10 deletions src/main/java/com/api/TaveShot/global/oauth2/GithubUserInfo.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@
package com.api.TaveShot.global.oauth2;

import static com.api.TaveShot.global.constant.OauthConstant.AVATAR_URL_PATTERN;
import static com.api.TaveShot.global.constant.OauthConstant.PROFILE_IMAGE_URL_PATTERN;
import static com.api.TaveShot.global.constant.OauthConstant.EMAIL_PATTERN;
import static com.api.TaveShot.global.constant.OauthConstant.ID_PATTERN;
import static com.api.TaveShot.global.constant.OauthConstant.LOGIN_PATTERN;
import static com.api.TaveShot.global.constant.OauthConstant.NAME_PATTERN;

import java.util.Map;
import lombok.Builder;

@Builder
public record GithubUserInfo(Map<String, Object> userInfo) {

public String getProfileImageUrl() {
return (String) userInfo.get(AVATAR_URL_PATTERN);
}

public String getLoginId() {
return (String) userInfo.get(LOGIN_PATTERN);
}

public String getName() {
return (String) userInfo.get(NAME_PATTERN);

public Integer getId() {
return (Integer) userInfo.get(ID_PATTERN);
}

public String getMail() {
return (String) userInfo.get(EMAIL_PATTERN);
}

public Long getId() {
return (Long) userInfo.get(ID_PATTERN);
public String getProfileImageUrl() {
return (String) userInfo.get(PROFILE_IMAGE_URL_PATTERN);
}
}

0 comments on commit 903c026

Please sign in to comment.