diff --git a/.github/workflows/dockerhub-push.yml b/.github/workflows/dockerhub-push.yml index c138e609..cb004510 100644 --- a/.github/workflows/dockerhub-push.yml +++ b/.github/workflows/dockerhub-push.yml @@ -12,74 +12,79 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout Repository - uses: actions/checkout@v2 + - name: Checkout Repository + uses: actions/checkout@v2 - - name: Set Environment Variables - run: | - BRANCH_NAME=$(echo $GITHUB_REF | awk -F'/' '{print $3}') - echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV + - name: Set Environment Variables + run: | + BRANCH_NAME=$(echo $GITHUB_REF | awk -F'/' '{print $3}') + echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_ENV - - name: Cache Gradle dependencies - uses: actions/cache@v2 - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - key: gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} - restore-keys: | - gradle- + - name: Cache Gradle dependencies + uses: actions/cache@v2 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + gradle- - - name: Set up JDK 17 - uses: actions/setup-java@v2 - with: - java-version: '17' - distribution: 'temurin' + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'temurin' - - name: Grant execute permission for gradlew - run: chmod +x src/${{ env.BRANCH_NAME }}-service/gradlew + - name: Grant execute permission for gradlew + run: chmod +x src/${{ env.BRANCH_NAME }}-service/gradlew - - name: Build with Gradle - env: - AUTH_MAIL_HOST: ${{ secrets.AUTH_MAIL_HOST }} - AUTH_MAIL_ADDRESS: ${{ secrets.AUTH_MAIL_ADDRESS }} - AUTH_MAIL_USERNAME: ${{ secrets.AUTH_MAIL_USERNAME }} - AUTH_MAIL_PASSWORD: ${{ secrets.AUTH_MAIL_PASSWORD }} - AUTH_MAIL_PORT: ${{ secrets.AUTH_MAIL_PORT }} + - name: Build with Gradle + env: + AUTH_MAIL_HOST: ${{ secrets.AUTH_MAIL_HOST }} + AUTH_MAIL_ADDRESS: ${{ secrets.AUTH_MAIL_ADDRESS }} + AUTH_MAIL_USERNAME: ${{ secrets.AUTH_MAIL_USERNAME }} + AUTH_MAIL_PASSWORD: ${{ secrets.AUTH_MAIL_PASSWORD }} + AUTH_MAIL_PORT: ${{ secrets.AUTH_MAIL_PORT }} + + AUTH_REDIS_HOST: ${{ secrets.AUTH_REDIS_HOST }} + AUTH_REDIS_PORT: ${{ secrets.AUTH_REDIS_PORT }} + AUTH_JWT_SECRET_KEY: ${{ secrets.AUTH_JWT_SECRET_KEY }} + + PASSPORT_KEY: ${{ secrets.PASSPORT_KEY }} + PASSPORT_ALGORITHM: ${{ secrets.PASSPORT_ALGORITHM }} + + run: | + cd src/${{ env.BRANCH_NAME }}-service + ./gradlew clean build -x test - AUTH_REDIS_HOST: ${{ secrets.AUTH_REDIS_HOST }} - AUTH_REDIS_PORT: ${{ secrets.AUTH_REDIS_PORT }} - AUTH_JWT_SECRET_KEY: ${{ secrets.AUTH_JWT_SECRET_KEY }} - - run: | - cd src/${{ env.BRANCH_NAME }}-service - ./gradlew clean build -x test - - - name: Build and Push Docker Image - env: - DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - BRANCH_NAME: ${{ env.BRANCH_NAME }} - - AUTH_MAIL_HOST: ${{ secrets.AUTH_MAIL_HOST }} - AUTH_MAIL_ADDRESS: ${{ secrets.AUTH_MAIL_ADDRESS }} - AUTH_MAIL_USERNAME: ${{ secrets.AUTH_MAIL_USERNAME }} - AUTH_MAIL_PASSWORD: ${{ secrets.AUTH_MAIL_PASSWORD }} - AUTH_MAIL_PORT: ${{ secrets.AUTH_MAIL_PORT }} - AUTH_REDIS_HOST: ${{ secrets.AUTH_REDIS_HOST }} - AUTH_REDIS_PORT: ${{ secrets.AUTH_REDIS_PORT }} - AUTH_JWT_SECRET_KEY: ${{ secrets.AUTH_JWT_SECRET_KEY }} - - run: | - if [ -n "$BRANCH_NAME" ]; then - DOCKERFILE_DIR="src/$BRANCH_NAME-service" - else - echo "Failed to extract branch name from GITHUB_REF." - exit 1 - fi - - cd $DOCKERFILE_DIR - docker run --privileged --rm tonistiigi/binfmt --install all - docker buildx create --use - docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD - docker buildx build --platform=linux/amd64,linux/arm64 -t $DOCKER_USERNAME/$BRANCH_NAME-service:latest . --push + - name: Build and Push Docker Image + env: + DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + BRANCH_NAME: ${{ env.BRANCH_NAME }} + + AUTH_MAIL_HOST: ${{ secrets.AUTH_MAIL_HOST }} + AUTH_MAIL_ADDRESS: ${{ secrets.AUTH_MAIL_ADDRESS }} + AUTH_MAIL_USERNAME: ${{ secrets.AUTH_MAIL_USERNAME }} + AUTH_MAIL_PASSWORD: ${{ secrets.AUTH_MAIL_PASSWORD }} + AUTH_MAIL_PORT: ${{ secrets.AUTH_MAIL_PORT }} + AUTH_REDIS_HOST: ${{ secrets.AUTH_REDIS_HOST }} + AUTH_REDIS_PORT: ${{ secrets.AUTH_REDIS_PORT }} + AUTH_JWT_SECRET_KEY: ${{ secrets.AUTH_JWT_SECRET_KEY }} + PASSPORT_KEY: ${{ secrets.PASSPORT_KEY }} + PASSPORT_ALGORITHM: ${{ secrets.PASSPORT_ALGORITHM }} + + run: | + if [ -n "$BRANCH_NAME" ]; then + DOCKERFILE_DIR="src/$BRANCH_NAME-service" + else + echo "Failed to extract branch name from GITHUB_REF." + exit 1 + fi + + cd $DOCKERFILE_DIR + docker run --privileged --rm tonistiigi/binfmt --install all + docker buildx create --use + docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD + docker buildx build --platform=linux/amd64,linux/arm64 -t $DOCKER_USERNAME/$BRANCH_NAME-service:latest . --push diff --git a/src/auth-service/Dockerfile b/src/auth-service/Dockerfile index b71cd8e5..87f8f2a8 100644 --- a/src/auth-service/Dockerfile +++ b/src/auth-service/Dockerfile @@ -8,6 +8,8 @@ ENV AUTH_MAIL_PORT=${AUTH_MAIL_PORT} ENV AUTH_REDIS_HOST=${AUTH_REDIS_HOST} ENV AUTH_REDIS_PORT=${AUTH_REDIS_PORT} ENV AUTH_JWT_SECRET_KEY=${AUTH_JWT_SECRET_KEY} +ENV PASSPORT_KEY=${PASSPORT_KEY} +ENV PASSPORT_KEY=${PASSPORT_KEY} ARG JAR_FILE=build/libs/easel-auth-service-0.0.1-SNAPSHOT.jar ADD ${JAR_FILE} easel-auth-service.jar diff --git a/src/auth-service/src/main/java/org/palette/easelauthservice/EaselAuthServiceApplication.java b/src/auth-service/src/main/java/org/palette/easelauthservice/EaselAuthServiceApplication.java index bc119aa4..6f73c955 100644 --- a/src/auth-service/src/main/java/org/palette/easelauthservice/EaselAuthServiceApplication.java +++ b/src/auth-service/src/main/java/org/palette/easelauthservice/EaselAuthServiceApplication.java @@ -1,8 +1,11 @@ package org.palette.easelauthservice; +import org.palette.config.CommonModuleConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Import; +@Import({CommonModuleConfig.class}) @SpringBootApplication public class EaselAuthServiceApplication { diff --git a/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/JwtAgent.java b/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/JwtAgent.java index 63f1b9aa..8485ab93 100644 --- a/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/JwtAgent.java +++ b/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/JwtAgent.java @@ -16,8 +16,8 @@ public class JwtAgent { private final JwtParser jwtParser; private static final int BEARER_PREFIX = 7; - public JwtPair provide(String email) { - return jwtGenerator.execute(email); + public JwtPair provide(Long id) { + return jwtGenerator.execute(id); } public void verify(String jwt) { @@ -26,7 +26,6 @@ public void verify(String jwt) { public Long parseUserId(String jwt) { jwt = jwt.substring(BEARER_PREFIX); - jwtVerifier.execute(jwt); - return jwtParser.getEmail(jwt); + return jwtParser.getId(jwt); } } diff --git a/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtGenerator.java b/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtGenerator.java index de18ec0d..c5713e93 100644 --- a/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtGenerator.java +++ b/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtGenerator.java @@ -15,9 +15,9 @@ public class JwtGenerator { private final JwtProperties jwtProperties; -public JwtPair execute(String email) { + public JwtPair execute(Long id) { return new JwtPair( - buildJwtToken(buildClaims(email), ACCESS_TOKEN_EXPIRE_TIME), + buildJwtToken(buildClaims(id), ACCESS_TOKEN_EXPIRE_TIME), buildJwtToken(Jwts.claims(), REFRESH_TOKEN_EXPIRE_TIME) ); } @@ -31,9 +31,9 @@ private String buildJwtToken(Claims claims, Long expiryTimeInMilliseconds) { .compact(); } - private Claims buildClaims(String email) { + private Claims buildClaims(Long id) { Claims claims = Jwts.claims(); - claims.put(JWT_CLAIMS_EMAIL_COMPONENT, email); + claims.put(JWT_CLAIMS_ID_COMPONENT, id); return claims; } diff --git a/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtParser.java b/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtParser.java index 9794ce1b..3dabe674 100644 --- a/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtParser.java +++ b/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtParser.java @@ -8,18 +8,20 @@ @RequiredArgsConstructor public class JwtParser { - private static final String EMAIL_FILED = "email"; + private static final String ID_FILED = "id"; private final JwtProperties jwtProperties; private final JwtVerifier jwtVerifier; - public Long getEmail(String token) { + public Long getId(String token) { jwtVerifier.execute(token); + Object id = Jwts.parserBuilder() .setSigningKey(jwtProperties.getSigningKey()) .build() .parseClaimsJws(token) - .getBody().get(EMAIL_FILED); + .getBody().get(ID_FILED); + return Long.valueOf(String.valueOf(id)); } } diff --git a/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtProperties.java b/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtProperties.java index 699febbf..4a2eff80 100644 --- a/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtProperties.java +++ b/src/auth-service/src/main/java/org/palette/easelauthservice/component/jwt/component/JwtProperties.java @@ -15,8 +15,7 @@ public class JwtProperties { protected static final String JWT_HEADER_PARAM_KEY = "type"; protected static final String JWT_HEADER_PARAM_VALUE = "JWT"; - protected static final String JWT_CLAIMS_SUBJECT = "jwt"; - protected static final String JWT_CLAIMS_EMAIL_COMPONENT = "email"; + protected static final String JWT_CLAIMS_ID_COMPONENT = "id"; protected static final Long ACCESS_TOKEN_EXPIRE_TIME = 30 * 60 * 1000L; // 30분 protected static final Long REFRESH_TOKEN_EXPIRE_TIME = 270 * 24 * 60 * 60 * 1000L; // 270일 diff --git a/src/auth-service/src/main/java/org/palette/easelauthservice/controller/AuthController.java b/src/auth-service/src/main/java/org/palette/easelauthservice/controller/AuthController.java index 9a9a401d..53d0a2b6 100644 --- a/src/auth-service/src/main/java/org/palette/easelauthservice/controller/AuthController.java +++ b/src/auth-service/src/main/java/org/palette/easelauthservice/controller/AuthController.java @@ -10,14 +10,10 @@ import org.palette.easelauthservice.dto.request.LoginRequest; import org.palette.easelauthservice.usecase.AuthUsecase; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequiredArgsConstructor -@RequestMapping("/auth") public class AuthController { private final AuthUsecase authUsecase; @@ -60,4 +56,13 @@ public ResponseEntity mobileLogin( .ok() .body(authUsecase.login(loginRequest)); } + + @PostMapping("/passport") + public ResponseEntity generatePassport( + @RequestHeader("Authorization") String jwtPayload + ) { + return ResponseEntity + .ok() + .body(authUsecase.validateJWT(jwtPayload)); + } } diff --git a/src/auth-service/src/main/java/org/palette/easelauthservice/external/GrpcServerByUserService.java b/src/auth-service/src/main/java/org/palette/easelauthservice/external/GrpcServer.java similarity index 92% rename from src/auth-service/src/main/java/org/palette/easelauthservice/external/GrpcServerByUserService.java rename to src/auth-service/src/main/java/org/palette/easelauthservice/external/GrpcServer.java index a2393601..3bf75a22 100644 --- a/src/auth-service/src/main/java/org/palette/easelauthservice/external/GrpcServerByUserService.java +++ b/src/auth-service/src/main/java/org/palette/easelauthservice/external/GrpcServer.java @@ -12,7 +12,7 @@ @GrpcService @RequiredArgsConstructor -public class GrpcServerByUserService extends GAuthServiceGrpc.GAuthServiceImplBase { +public class GrpcServer extends GAuthServiceGrpc.GAuthServiceImplBase { private final RedisEmailAuthService redisEmailAuthService; private final EmailAuthMailSender emailAuthMailSender; @@ -37,7 +37,7 @@ public void sendEmailAuth( ); GSendEmailAuthResponse response = GSendEmailAuthResponse.newBuilder() - .setMessage(true) + .setIsSuccess(true) .build(); responseObserver.onNext(response); responseObserver.onCompleted(); diff --git a/src/auth-service/src/main/java/org/palette/easelauthservice/external/GrpcUserClient.java b/src/auth-service/src/main/java/org/palette/easelauthservice/external/GrpcUserClient.java index fc884e2e..5d9153d9 100644 --- a/src/auth-service/src/main/java/org/palette/easelauthservice/external/GrpcUserClient.java +++ b/src/auth-service/src/main/java/org/palette/easelauthservice/external/GrpcUserClient.java @@ -4,9 +4,7 @@ import net.devh.boot.grpc.client.inject.GrpcClient; import org.palette.easelauthservice.exception.BaseException; import org.palette.easelauthservice.exception.ExceptionType; -import org.palette.grpc.GCheckEmailAndPasswordRequest; -import org.palette.grpc.GUpdateUserAuthStatusRequest; -import org.palette.grpc.GUserServiceGrpc; +import org.palette.grpc.*; import org.springframework.stereotype.Component; @Component @@ -28,16 +26,30 @@ public void updateUserAuthStatus(String email) { } } - public void checkEmailWithPassword(String email, String password) { + public Long checkEmailWithPassword(String email, String password) { try { - gUserServiceBlockingStub.checkEmailAndPassword( + return gUserServiceBlockingStub.checkEmailAndPassword( GCheckEmailAndPasswordRequest.newBuilder() .setEmail(email) .setPassword(password) .build() + ).getUserId(); + + } catch (final Exception e) { + throw new BaseException(ExceptionType.AUTH_500_000001); + } + } + + public GLoadUserInfoFromIdResponse loadById(Long id) { + try { + return gUserServiceBlockingStub.loadUserInfoFromId( + GLoadUserInfoFromIdRequest.newBuilder() + .setId(id) + .build() ); } catch (final Exception e) { throw new BaseException(ExceptionType.AUTH_500_000001); } } + } diff --git a/src/auth-service/src/main/java/org/palette/easelauthservice/usecase/AuthUsecase.java b/src/auth-service/src/main/java/org/palette/easelauthservice/usecase/AuthUsecase.java index b2f134d8..3a79e285 100644 --- a/src/auth-service/src/main/java/org/palette/easelauthservice/usecase/AuthUsecase.java +++ b/src/auth-service/src/main/java/org/palette/easelauthservice/usecase/AuthUsecase.java @@ -11,6 +11,9 @@ import org.palette.easelauthservice.redis.EmailAuth; import org.palette.easelauthservice.redis.RedisEmailAuthService; import org.palette.grpc.GAuthServiceGrpc; +import org.palette.grpc.GLoadUserInfoFromIdResponse; +import org.palette.passport.PassportGenerator; +import org.palette.passport.component.UserInfo; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -23,6 +26,7 @@ public class AuthUsecase extends GAuthServiceGrpc.GAuthServiceImplBase { private final EmailAuthMailSender emailAuthMailSender; private final GrpcUserClient grpcUserClient; private final JwtAgent jwtAgent; + private final PassportGenerator passportGenerator; public void verifyEmail(EmailAuthRequest emailAuthRequest) { String email = emailAuthRequest.email(); @@ -52,8 +56,27 @@ public JwtPair login(LoginRequest loginRequest) { String email = loginRequest.email(); String password = loginRequest.password(); - grpcUserClient.checkEmailWithPassword(email, password); + return jwtAgent.provide( + grpcUserClient.checkEmailWithPassword(email, password) + ); + } + + public String validateJWT(String jwtPayload) { + Long userId = jwtAgent.parseUserId(jwtPayload); + GLoadUserInfoFromIdResponse gLoadUserInfoFromIdResponse = grpcUserClient.loadById(userId); - return jwtAgent.provide(email); + return passportGenerator.generatePassport( + new UserInfo( + userId, + gLoadUserInfoFromIdResponse.getEmail(), + gLoadUserInfoFromIdResponse.getNickname(), + gLoadUserInfoFromIdResponse.getUsername(), + gLoadUserInfoFromIdResponse.getRole(), + gLoadUserInfoFromIdResponse.getIsActivated(), + gLoadUserInfoFromIdResponse.getAccessedAt(), + gLoadUserInfoFromIdResponse.getCreatedAt(), + gLoadUserInfoFromIdResponse.getDeletedAt() + ) + ); } } diff --git a/src/auth-service/src/main/resources/application.yml b/src/auth-service/src/main/resources/application.yml index a6acf60a..81fa1e12 100644 --- a/src/auth-service/src/main/resources/application.yml +++ b/src/auth-service/src/main/resources/application.yml @@ -49,3 +49,7 @@ grpc: enableKeepAlive: true keepAliveWithoutCalls: true negotiationType: plaintext + +passport: + key: ${PASSPORT_KEY} + algorithm: ${PASSPORT_ALGORITHM} diff --git a/src/common-module/build.gradle b/src/common-module/build.gradle index 3d938f0d..efca7777 100644 --- a/src/common-module/build.gradle +++ b/src/common-module/build.gradle @@ -58,3 +58,7 @@ test { clean { delete 'src/generated' } + +bootJar { + enabled = false +} diff --git a/src/common-module/src/main/java/org/palette/config/CommonModuleConfig.java b/src/common-module/src/main/java/org/palette/config/CommonModuleConfig.java new file mode 100644 index 00000000..55b1e749 --- /dev/null +++ b/src/common-module/src/main/java/org/palette/config/CommonModuleConfig.java @@ -0,0 +1,44 @@ +package org.palette.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.RequiredArgsConstructor; +import org.palette.passport.HMACEncoder; +import org.palette.passport.PassportExtractor; +import org.palette.passport.PassportGenerator; +import org.palette.passport.PassportValidator; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@RequiredArgsConstructor +public class CommonModuleConfig { + + private final ObjectMapper objectMapper; + + @Value("${passport.algorithm}") + String HMacAlgorithm; + + @Value("${passport.key}") + String passportSecretKey; + + @Bean + public HMACEncoder hmacEncoder() { + return new HMACEncoder(HMacAlgorithm, passportSecretKey); + } + + @Bean + public PassportGenerator passportGenerator() { + return new PassportGenerator(objectMapper, hmacEncoder()); + } + + @Bean + public PassportValidator passportValidator() { + return new PassportValidator(objectMapper, hmacEncoder()); + } + + @Bean + public PassportExtractor passportExtractor() { + return new PassportExtractor(objectMapper, passportValidator()); + } +} diff --git a/src/common-module/src/main/java/org/palette/passport/HMACEncoder.java b/src/common-module/src/main/java/org/palette/passport/HMACEncoder.java index 5e3319fa..2e93f63f 100644 --- a/src/common-module/src/main/java/org/palette/passport/HMACEncoder.java +++ b/src/common-module/src/main/java/org/palette/passport/HMACEncoder.java @@ -1,24 +1,17 @@ package org.palette.passport; -import org.springframework.beans.factory.annotation.Value; +import lombok.RequiredArgsConstructor; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; +@RequiredArgsConstructor public class HMACEncoder { private final String HMacAlgorithm; private final String passportSecretKey; - public HMACEncoder( - @Value("${passport.algorithm}") String HMacAlgorithm, - @Value("${passport.key}") String passportSecretKey - ) { - this.HMacAlgorithm = HMacAlgorithm; - this.passportSecretKey = passportSecretKey; - } - protected String createHMACIntegrityKey(String userInfoString) { SecretKeySpec secretKeySpec = new SecretKeySpec( passportSecretKey.getBytes(), diff --git a/src/common-module/src/main/java/org/palette/passport/PassportExtractor.java b/src/common-module/src/main/java/org/palette/passport/PassportExtractor.java index 43e8046a..9d16c6b0 100644 --- a/src/common-module/src/main/java/org/palette/passport/PassportExtractor.java +++ b/src/common-module/src/main/java/org/palette/passport/PassportExtractor.java @@ -2,35 +2,53 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.palette.exception.BaseException; import org.palette.exception.ExceptionType; +import org.palette.passport.component.Passport; import org.palette.passport.component.UserInfo; +import org.springframework.stereotype.Component; import java.util.Base64; +@Component @RequiredArgsConstructor public class PassportExtractor { private static final String USER_INFO = "userInfo"; + private static final String AUTHORIZATION_HEADER_NAME = "Authorization"; private final ObjectMapper objectMapper; + private final PassportValidator passportValidator; - public UserInfo getUserInfo(String requestedPassport) { - UserInfo userInfo; + public Passport getPassportFromRequestHeader(HttpServletRequest httpServletRequest) { try { - String passportStr = new String( - Base64.getDecoder().decode(requestedPassport) + return objectMapper.readValue( + httpServletRequest.getHeader(AUTHORIZATION_HEADER_NAME), + Passport.class ); - String userInfoString = objectMapper.readTree(passportStr) + } catch (JsonProcessingException e) { + throw new BaseException(ExceptionType.COMMON_500_000002); + } + } + + public UserInfo getUserInfoByPassport(Passport passport) { + try { + String passportString = new String( + Base64.getDecoder().decode(passport.toString()) + ); + + passportValidator.validatePassport(passportString); + + String userInfoString = objectMapper.readTree(passportString) .get(USER_INFO) .toString(); - userInfo = objectMapper.readValue( + return objectMapper.readValue( userInfoString, UserInfo.class ); } catch (JsonProcessingException e) { throw new BaseException(ExceptionType.COMMON_500_000002); } - return userInfo; } } diff --git a/src/common-module/src/main/java/org/palette/passport/PassportGenerator.java b/src/common-module/src/main/java/org/palette/passport/PassportGenerator.java index 80098752..f576498a 100644 --- a/src/common-module/src/main/java/org/palette/passport/PassportGenerator.java +++ b/src/common-module/src/main/java/org/palette/passport/PassportGenerator.java @@ -7,13 +7,14 @@ import org.palette.exception.ExceptionType; import org.palette.passport.component.Passport; import org.palette.passport.component.UserInfo; +import org.springframework.stereotype.Component; import java.util.Base64; +@Component @RequiredArgsConstructor public class PassportGenerator { - private static final String USER_INFO = "userInfo"; - private static final String INTEGRITY_KEY = "integrityKey"; + private final ObjectMapper objectMapper; private final HMACEncoder hmacEncoder; diff --git a/src/common-module/src/main/java/org/palette/passport/PassportValidator.java b/src/common-module/src/main/java/org/palette/passport/PassportValidator.java index d0ba831f..94d90312 100644 --- a/src/common-module/src/main/java/org/palette/passport/PassportValidator.java +++ b/src/common-module/src/main/java/org/palette/passport/PassportValidator.java @@ -4,9 +4,11 @@ import lombok.RequiredArgsConstructor; import org.palette.exception.BaseException; import org.palette.exception.ExceptionType; +import org.springframework.stereotype.Component; import java.util.Base64; +@Component @RequiredArgsConstructor public class PassportValidator { @@ -15,7 +17,7 @@ public class PassportValidator { private final ObjectMapper objectMapper; private final HMACEncoder hmacEncoder; - public boolean validatePassport(String requestedPassport) { + public void validatePassport(String requestedPassport) { String encodedUserInfo; String integrityKey; @@ -36,7 +38,6 @@ public boolean validatePassport(String requestedPassport) { throw new BaseException(ExceptionType.COMMON_500_000002); } - return true; } private void isEqualByRequestedPassport( diff --git a/src/common-module/src/main/proto/auth_service.proto b/src/common-module/src/main/proto/auth_service.proto index a423ad58..16d68887 100644 --- a/src/common-module/src/main/proto/auth_service.proto +++ b/src/common-module/src/main/proto/auth_service.proto @@ -5,6 +5,15 @@ option java_package = "org.palette.grpc"; service GAuthService { rpc SendEmailAuth (GSendEmailAuthRequest) returns (GSendEmailAuthResponse) {} + rpc ValidateJWT (GValidateJWTRequest) returns (GValidateJWTResponse) {} +} + +message GValidateJWTRequest { + string jwtPayload = 1; +} + +message GValidateJWTResponse { + string passportPayload = 1; } message GSendEmailAuthRequest { @@ -12,5 +21,5 @@ message GSendEmailAuthRequest { } message GSendEmailAuthResponse { - bool message = 1; + bool isSuccess = 1; } diff --git a/src/common-module/src/main/proto/passport.proto b/src/common-module/src/main/proto/passport.proto index 06b5a083..7a22111c 100644 --- a/src/common-module/src/main/proto/passport.proto +++ b/src/common-module/src/main/proto/passport.proto @@ -3,7 +3,7 @@ syntax = "proto3"; option java_multiple_files = true; option java_package = "org.palette.grpc"; -message Passport { +message GPassport { int64 id = 1; string email = 2; string nickname = 3; @@ -13,4 +13,5 @@ message Passport { string accessedAt = 7; string createdAt = 8; string deletedAt = 9; + string integrityKey = 10; } diff --git a/src/common-module/src/main/proto/social_service.proto b/src/common-module/src/main/proto/social_service.proto index 56422e74..36027199 100644 --- a/src/common-module/src/main/proto/social_service.proto +++ b/src/common-module/src/main/proto/social_service.proto @@ -22,7 +22,7 @@ message GCreateUserResponse { } message GFollowerIdsRequest { - Passport passport = 1; + int64 userId = 2; } message GFollowerIdsResponse { diff --git a/src/common-module/src/main/proto/user_service.proto b/src/common-module/src/main/proto/user_service.proto index 7a29089b..63f83b99 100644 --- a/src/common-module/src/main/proto/user_service.proto +++ b/src/common-module/src/main/proto/user_service.proto @@ -6,6 +6,7 @@ option java_package = "org.palette.grpc"; service GUserService { rpc UpdateUserAuthStatus (GUpdateUserAuthStatusRequest) returns (GUpdateUserAuthStatusResponse) {} rpc CheckEmailAndPassword (GCheckEmailAndPasswordRequest) returns (GCheckEmailAndPasswordResponse) {} + rpc LoadUserInfoFromId (GLoadUserInfoFromIdRequest) returns (GLoadUserInfoFromIdResponse) {} } message GUpdateUserAuthStatusRequest { @@ -17,10 +18,26 @@ message GCheckEmailAndPasswordRequest { string password = 3; } +message GLoadUserInfoFromIdRequest { + int64 id = 1; +} + +message GLoadUserInfoFromIdResponse { + string email = 2; + string nickname = 3; + string username = 4; + string role = 5; + bool isActivated = 6; + string accessedAt = 7; + string createdAt = 8; + string deletedAt = 9; +} + message GUpdateUserAuthStatusResponse { bool isSuccess = 1; } message GCheckEmailAndPasswordResponse { bool isSuccess = 1; + int64 userId = 2; }