Skip to content

Commit

Permalink
Merge pull request #205 from TEAM-SAMSION/PET-300
Browse files Browse the repository at this point in the history
  • Loading branch information
tlarbals824 authored Feb 8, 2024
2 parents 78ec693 + 4d0f9f0 commit 144db13
Show file tree
Hide file tree
Showing 68 changed files with 545 additions and 442 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ public record UserSignUpEvent(
String email,
Provider provider
) {
public static UserSignUpEvent of(String nickname, String email, Provider provider) {
return new UserSignUpEvent(nickname, email, provider);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class SecurityUtils {

public static String getAuthenticationPrincipal() {
final String email = (String)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
return email;
public static Long getAuthenticationPrincipal() {
return (Long)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
}
}
3 changes: 3 additions & 0 deletions Domain-Module/Auth-Module/Auth-Application/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ dependencies {

// webclinet
implementation 'org.springframework.boot:spring-boot-starter-webflux'

// user
implementation project(':Domain-Module:User-Module:User-Domain')
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.pawith.authapplication.dto;

import com.pawith.commonmodule.enums.Provider;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import com.pawith.commonmodule.enums.Provider;
import lombok.NoArgsConstructor;

@Getter
Expand All @@ -12,4 +12,5 @@
public class OAuthRequest {
private Provider provider;
private String accessToken;
private String refreshToken; // nullable
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
@RequiredArgsConstructor
public class OAuthUserInfo {
private final String username;
private final String email;
private final String email; // email -> sub, 사용자 식별 정보를 email에서 sub로 변경
private final String sub;
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.pawith.authapplication.service;

public interface JWTExtractUserDetailsUseCase<T> {
T extract(final String token);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@

public interface OAuthUseCase {

OAuthResponse oAuthLogin(Provider provider, String accessToken);
OAuthResponse oAuthLogin(Provider provider, String accessToken, String refreshToken);

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package com.pawith.authapplication.service.impl;

import com.pawith.authapplication.service.JWTExtractEmailUseCase;
import com.pawith.authapplication.service.JWTExtractUserDetailsUseCase;
import com.pawith.authdomain.jwt.JWTProvider;
import com.pawith.authdomain.jwt.TokenType;
import com.pawith.commonmodule.annotation.ApplicationService;
import lombok.RequiredArgsConstructor;

@ApplicationService
@RequiredArgsConstructor
public class JWTExtractEmailUseCaseImpl implements JWTExtractEmailUseCase {
public class JWTExtractUserDetailsUseCaseImpl implements JWTExtractUserDetailsUseCase<Long> {
private final JWTProvider jwtProvider;

@Override
public String extractEmail(final String token){
return jwtProvider.extractEmailFromToken(token, TokenType.ACCESS_TOKEN);
public Long extract(final String token) {
return jwtProvider.extractUserClaimsFromToken(token, TokenType.ACCESS_TOKEN)
.getUserId();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.pawith.authapplication.dto.OAuthRequest;
import com.pawith.authapplication.dto.OAuthResponse;
import com.pawith.authapplication.service.OAuthUseCase;
import com.pawith.authapplication.service.command.OAuthInvoker;
import com.pawith.authapplication.service.oauth.OAuthInvoker;
import com.pawith.commonmodule.annotation.ApplicationService;
import com.pawith.commonmodule.enums.Provider;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,7 +15,7 @@ public class OAuthUseCaseImpl implements OAuthUseCase {
private final OAuthInvoker oAuthInvoker;

@Override
public OAuthResponse oAuthLogin(Provider provider, String accessToken){
return oAuthInvoker.execute(new OAuthRequest(provider, accessToken));
public OAuthResponse oAuthLogin(Provider provider, String accessToken, String refreshToken){
return oAuthInvoker.execute(new OAuthRequest(provider, accessToken, refreshToken));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.pawith.authapplication.service.ReissueUseCase;
import com.pawith.authapplication.utils.TokenExtractUtils;
import com.pawith.authdomain.jwt.JWTProvider;
import com.pawith.authdomain.jwt.PrivateClaims;
import com.pawith.authdomain.jwt.TokenType;
import com.pawith.authdomain.service.TokenDeleteService;
import com.pawith.authdomain.service.TokenLockService;
Expand All @@ -30,21 +31,22 @@ public class ReissueUseCaseImpl implements ReissueUseCase {
public TokenReissueResponse reissue(String refreshTokenHeader) {
final String refreshToken = TokenExtractUtils.extractToken(refreshTokenHeader);
jwtProvider.validateToken(refreshToken, TokenType.REFRESH_TOKEN);
final String userEmail = jwtProvider.extractEmailFromToken(refreshToken, TokenType.REFRESH_TOKEN);
return reissueToken(refreshToken, userEmail);
final PrivateClaims.UserClaims userClaims = jwtProvider.extractUserClaimsFromToken(refreshToken, TokenType.REFRESH_TOKEN);
return reissueToken(refreshToken, userClaims);
}

private TokenReissueResponse reissueToken(final String refreshToken,final String userEmail) {
private TokenReissueResponse reissueToken(final String refreshToken,final PrivateClaims.UserClaims userClaims) {
final String lockKey = userClaims.toString();
try {
tokenLockService.lockToken(userEmail);
tokenLockService.lockToken(lockKey);
if (jwtProvider.existsCachedRefreshToken(refreshToken)) {
return generateToken(jwtProvider::getCachedToken, refreshToken);
}
tokenValidateService.validateIsExistToken(refreshToken, TokenType.REFRESH_TOKEN);
tokenDeleteService.deleteTokenByValue(refreshToken);
return generateAndSaveToken(jwtProvider::reIssueToken, refreshToken, userEmail);
return generateAndSaveToken(jwtProvider::reIssueToken, refreshToken, userClaims.getUserId());
} finally {
tokenLockService.releaseLockToken(userEmail);
tokenLockService.releaseLockToken(lockKey);
}
}

Expand All @@ -54,9 +56,9 @@ private TokenReissueResponse generateToken(final Function<String, JWTProvider.To
final String generatedRefreshToken = AuthConsts.AUTHENTICATION_TYPE_PREFIX + token.refreshToken();
return new TokenReissueResponse(generatedAccessToken, generatedRefreshToken);
}
private TokenReissueResponse generateAndSaveToken(final Function<String, JWTProvider.Token> tokenGenerator,final String refreshToken,final String userEmail) {
private TokenReissueResponse generateAndSaveToken(final Function<String, JWTProvider.Token> tokenGenerator,final String refreshToken,final Long userId) {
final JWTProvider.Token token = tokenGenerator.apply(refreshToken);
tokenSaveService.saveToken(token.refreshToken(), userEmail, TokenType.REFRESH_TOKEN);
tokenSaveService.saveToken(token.refreshToken(), TokenType.REFRESH_TOKEN, userId);
return generateToken(inputRefreshToken -> token, refreshToken);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.pawith.authapplication.service.command.handler;
package com.pawith.authapplication.service.oauth;

import com.pawith.authapplication.dto.OAuthRequest;
import com.pawith.authapplication.dto.OAuthUserInfo;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.pawith.authapplication.service.oauth;

import com.pawith.authapplication.consts.AuthConsts;
import com.pawith.authapplication.dto.OAuthRequest;
import com.pawith.authapplication.dto.OAuthResponse;
import com.pawith.authapplication.dto.OAuthUserInfo;
import com.pawith.authapplication.exception.AuthException;
import com.pawith.authdomain.exception.AuthError;
import com.pawith.authdomain.jwt.JWTProvider;
import com.pawith.authdomain.jwt.PrivateClaims;
import com.pawith.authdomain.jwt.TokenType;
import com.pawith.authdomain.service.TokenSaveService;
import com.pawith.userdomain.service.UserQueryService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.List;

@Component
@RequiredArgsConstructor
public class OAuthInvoker {
private final List<AuthHandler> authHandlerList;
private final JWTProvider jwtProvider;
private final TokenSaveService tokenSaveService;
private final ApplicationEventPublisher publisher;
// private final OAuthModifyingService oAuthModifyingService;
// private final OAuthQueryService oAuthQueryService;
// private final OAuthSaveService oAuthSaveService;
private final UserQueryService userQueryService;
private final TransactionTemplate transactionTemplate;

public OAuthResponse execute(OAuthRequest request){
// oauth 정보가 없으면 생성
// 생성하고 조회, email이 없어도 될지, user에서 email, provider는 제거
// oauth에는 userId를 넣는다?
// 있으면 그대로 진행
final OAuthUserInfo oAuthUserInfo = attemptLogin(request);
saveOAuthAndPublishEvent(request, oAuthUserInfo);
return generateServerAuthenticationTokens(PrivateClaims.UserClaims.of(userQueryService.findByEmail(oAuthUserInfo.getEmail()).getId()));
}

private void saveOAuthAndPublishEvent(OAuthRequest request, OAuthUserInfo oAuthUserInfo) {
transactionTemplate.execute(status -> {
/**
* OAuth 정보가 이미 존재하면, OAuth 정보를 조회하고 이메일 정보가 변경되면 UserEmailUpdateEvent를 발행한다.
* OAuth 존재하지 않으면 새로운 OAuth 정보를 생성한다. 이후에 UserSignUpEvent를 발행하여 사용자의 가입을 알린다.
*/
// if(oAuthQueryService.isOAuthExist(oAuthUserInfo.getSub())){
// final OAuth oAuth = oAuthQueryService.findBySub(oAuthUserInfo.getSub());
// oAuthModifyingService.
// } else{
// publisher.publishEvent(UserSignUpEvent.of(oAuthUserInfo.getUsername(), oAuthUserInfo.getEmail(), request.getProvider()));
// oAuthSaveService.saveOAuthUser(
// OAuth.of(
// request.getProvider(),
// request.getRefreshToken(),
// oAuthUserInfo.getEmail(),
// oAuthUserInfo.getSub(),
// userQueryService.findByEmail(oAuthUserInfo.getEmail()).getId()
// )
// );
// }
// return null;
return null;
});
}

private OAuthUserInfo attemptLogin(OAuthRequest request) {
for (AuthHandler authHandler : authHandlerList) {
if (authHandler.isAccessible(request)) {
return authHandler.handle(request);
}
}
throw new AuthException(AuthError.OAUTH_FAIL);
}

private OAuthResponse generateServerAuthenticationTokens(PrivateClaims.UserClaims userClaims) {
final JWTProvider.Token token = jwtProvider.generateToken(userClaims);
tokenSaveService.saveToken(token.refreshToken(), TokenType.REFRESH_TOKEN, userClaims.getUserId());
final String accessToken = AuthConsts.AUTHENTICATION_TYPE_PREFIX + token.accessToken();
final String refreshToken = AuthConsts.AUTHENTICATION_TYPE_PREFIX + token.refreshToken();
return OAuthResponse.builder()
.accessToken(accessToken)
.refreshToken(refreshToken)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.pawith.authapplication.service.command.feign;
package com.pawith.authapplication.service.oauth.feign;

import com.pawith.authapplication.service.command.feign.response.Keys;
import com.pawith.authapplication.service.oauth.feign.response.Keys;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.pawith.authapplication.service.command.feign;
package com.pawith.authapplication.service.oauth.feign;

import com.pawith.authapplication.service.command.feign.response.GoogleUserInfo;
import com.pawith.authapplication.service.oauth.feign.response.GoogleUserInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.pawith.authapplication.service.command.feign;
package com.pawith.authapplication.service.oauth.feign;

import com.pawith.authapplication.service.command.feign.response.KakaoUserInfo;
import com.pawith.authapplication.service.command.feign.response.TokenInfo;
import com.pawith.authapplication.service.oauth.feign.response.KakaoUserInfo;
import com.pawith.authapplication.service.oauth.feign.response.TokenInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.pawith.authapplication.service.command.feign;
package com.pawith.authapplication.service.oauth.feign;

import com.pawith.authapplication.service.command.feign.response.NaverUserInfo;
import com.pawith.authapplication.service.oauth.feign.response.NaverUserInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.pawith.authapplication.service.command.feign.response;
package com.pawith.authapplication.service.oauth.feign.response;

import lombok.AccessLevel;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.pawith.authapplication.service.command.feign.response;
package com.pawith.authapplication.service.oauth.feign.response;

import com.fasterxml.jackson.annotation.JsonAlias;
import lombok.AccessLevel;
Expand Down
Loading

0 comments on commit 144db13

Please sign in to comment.