Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [AUTH] Gateway와 통신하는 API Endpoint 를 추가합니다. #138

Merged
merged 24 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7d4273e
fix: update build.gradle
doxxx93 Jan 29, 2024
0ff12b1
refactor : Passport 추출 방식 수정
K-Diger Jan 29, 2024
62a8e0e
refactor : 프로토버퍼 수정 (message -> isSuccess, JWTValidateDTO)
K-Diger Jan 29, 2024
cba9228
Merge remote-tracking branch 'origin/common' into auth/feat#136
K-Diger Jan 29, 2024
b638f72
feat : UserService Proto LoadById
K-Diger Jan 29, 2024
bd7bae8
Merge remote-tracking branch 'origin/common' into auth/feat#136
K-Diger Jan 29, 2024
02d3181
refactor : Passport 관련 클래스 빈 환경설정 등록
K-Diger Jan 29, 2024
1fdfbad
Merge remote-tracking branch 'origin/common' into auth/feat#136
K-Diger Jan 29, 2024
0992111
refactor : GSendEmailAuthResponse 필드 수정
K-Diger Jan 29, 2024
3654e78
refactor : gRPCGatewayServer 추가
K-Diger Jan 29, 2024
7741520
refactor : passport 환경변수 추가
K-Diger Jan 29, 2024
59f1b90
refactor : gRPC 서버 통합
K-Diger Jan 29, 2024
86f24e1
docs : Dockerfile 내 passport 환경변수 추가
K-Diger Jan 29, 2024
1962e86
feat: user spring's ObjectMapper
210-reverof Jan 29, 2024
f27493e
Merge remote-tracking branch 'origin/common' into auth/feat#136
K-Diger Jan 30, 2024
fdb5138
refactor : 로그인 gRPC 응답값 변경
K-Diger Jan 30, 2024
9f68094
Merge remote-tracking branch 'origin/common' into common
K-Diger Jan 30, 2024
620ee22
Merge remote-tracking branch 'origin/common' into auth/feat#136
K-Diger Jan 30, 2024
d992dd5
feat : AuthUsecase JWT검증 및 패스포트 발급 추가
K-Diger Jan 30, 2024
89f1ec2
refactor : JWT 필드 수정 email -> id
K-Diger Jan 30, 2024
27fdb9e
feat : AuthService GrpcServer JwtValidate/Passport발급 기능 추가
K-Diger Jan 30, 2024
425a1ba
feat : passport 발급 엔드포인트 추가
K-Diger Jan 30, 2024
5970a16
refactor : GrpcUserClient checkEmailWithPassword 반환값 수정
K-Diger Jan 30, 2024
00ffddf
refactor : github actions script 패스포트 추가
K-Diger Jan 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 70 additions & 65 deletions .github/workflows/dockerhub-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 2 additions & 0 deletions src/auth-service/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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 {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)
);
}
Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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일

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -60,4 +56,13 @@ public ResponseEntity<JwtPair> mobileLogin(
.ok()
.body(authUsecase.login(loginRequest));
}

@PostMapping("/passport")
public ResponseEntity<String> generatePassport(
@RequestHeader("Authorization") String jwtPayload
) {
return ResponseEntity
.ok()
.body(authUsecase.validateJWT(jwtPayload));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -37,7 +37,7 @@ public void sendEmailAuth(
);

GSendEmailAuthResponse response = GSendEmailAuthResponse.newBuilder()
.setMessage(true)
.setIsSuccess(true)
.build();
responseObserver.onNext(response);
responseObserver.onCompleted();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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();
Expand Down Expand Up @@ -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()
)
);
}
}
4 changes: 4 additions & 0 deletions src/auth-service/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@ grpc:
enableKeepAlive: true
keepAliveWithoutCalls: true
negotiationType: plaintext

passport:
key: ${PASSPORT_KEY}
algorithm: ${PASSPORT_ALGORITHM}
4 changes: 4 additions & 0 deletions src/common-module/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,7 @@ test {
clean {
delete 'src/generated'
}

bootJar {
enabled = false
}
Loading