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/#47 #62

Merged
merged 2 commits into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Backend CD # actions ์ด๋ฆ„

on:
push:
branches: [ develop ]
branches: [ feat/#47 ]

jobs:
deploy:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.pocket.domain.port.user;

import com.pocket.domain.dto.user.LoginResponse;
import com.pocket.domain.dto.user.UserInfoDTO;

public interface LoadUserInfoPort {

UserInfoDTO loadUserInfo(String name);

LoginResponse createToken(String email);

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.pocket.domain.service.user;

import com.pocket.domain.dto.user.LoginResponse;
import com.pocket.domain.dto.user.UserInfoDTO;
import com.pocket.domain.port.user.LoadUserInfoPort;
import com.pocket.domain.usecase.user.LoginUseCase;
Expand All @@ -15,4 +16,8 @@ public class UserQueryService implements LoginUseCase {
public UserInfoDTO getUserInfo(String name) {
return loadUserInfoPort.loadUserInfo(name);
}

public LoginResponse reissueToken(String email) {
return loadUserInfoPort.createToken(email);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.pocket.domain.usecase.user;

import com.pocket.domain.dto.user.LoginResponse;
import com.pocket.domain.dto.user.UserInfoDTO;

public interface LoginUseCase {

UserInfoDTO getUserInfo(String name);

LoginResponse reissueToken(String email);
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.pocket.inbounds.user.presentation;

import com.pocket.core.aop.annotation.NameAuthenticated;
import com.pocket.core.exception.common.ApplicationResponse;
import com.pocket.domain.dto.user.LoginResponse;
import com.pocket.domain.dto.user.UserInfoDTO;
import com.pocket.domain.usecase.user.LoginUseCase;
import com.pocket.inbounds.user.response.UserResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -27,4 +28,12 @@ public ApplicationResponse<UserResponse> getUserInfo(
UserResponse response = new UserResponse(userInfoDTO.name(), userInfoDTO.email(), userInfoDTO.image());
return ApplicationResponse.ok(response);
}

@GetMapping(value = "/reissue", produces = MediaType.APPLICATION_JSON_VALUE)
public ApplicationResponse<LoginResponse> refresh(
@AuthenticationPrincipal UserInfoDTO userInfoDTO
) {
LoginResponse tokenResponse = loginUseCase.reissueToken(userInfoDTO.email());
return ApplicationResponse.ok(tokenResponse);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ public interface UserControllerDocs {
@Operation(summary = "์‚ฌ์šฉ์ž ์ •๋ณด ์ œ๊ณต", description = "์‚ฌ์šฉ์ž ์ •๋ณด ์ „๋‹ฌ API")
ApplicationResponse<UserResponse> getUserInfo(
@AuthenticationPrincipal UserInfoDTO userInfoDTO);


}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import com.pocket.core.exception.user.UserCustomException;
import com.pocket.core.exception.user.UserErrorCode;
import com.pocket.domain.dto.user.LoginResponse;
import com.pocket.domain.dto.user.UserInfoDTO;
import com.pocket.domain.port.user.LoadUserInfoPort;
import com.pocket.outbound.entity.JpaUser;
import com.pocket.outbound.repository.UserRepository;
import com.pocket.outbound.util.JwtUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

Expand All @@ -14,6 +16,7 @@
public class UserAdapter implements LoadUserInfoPort {

private final UserRepository userRepository;
private final JwtUtil jwtUtil;

public UserInfoDTO loadUserInfo(String name) {
JpaUser user = userRepository.findByUserName(name)
Expand All @@ -22,10 +25,18 @@ public UserInfoDTO loadUserInfo(String name) {
return new UserInfoDTO(user.getUser().getName(), user.getUser().getEmail(), user.getUser().getPicture());
}

public UserInfoDTO loadUserInfoByEmail(String email) {
JpaUser user = userRepository.findByUserEmail(email)
.orElseThrow(() -> new UserCustomException(UserErrorCode.NO_USER_INFO));
public LoginResponse createToken(String email) {

return new UserInfoDTO(user.getUser().getName(), user.getUser().getEmail(), user.getUser().getPicture());
final JpaUser user = findUser(email);

String accessToken = jwtUtil.createJwtAccessToken(user.getUser().getEmail(), user.getUser().getSubId());
String refreshToken = jwtUtil.createJwtRefreshToken(user.getUser().getEmail(), user.getUser().getSubId());

return new LoginResponse(accessToken, refreshToken);
}

private JpaUser findUser(String email) {
return userRepository.findByUserEmail(email)
.orElseThrow(() -> new UserCustomException(UserErrorCode.NO_USER_INFO));
}
}
25 changes: 17 additions & 8 deletions outbound/src/main/java/com/pocket/outbound/util/JwtUtil.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.pocket.outbound.util;

import com.pocket.core.exception.jwt.SecurityCustomException;
import com.pocket.core.exception.user.UserCustomException;
import com.pocket.core.exception.user.UserErrorCode;
import com.pocket.core.redis.util.RedisUtil;
import com.pocket.domain.dto.user.LoginResponse;
import com.pocket.domain.dto.user.UserInfoDTO;
import com.pocket.outbound.adapter.user.UserAdapter;
import com.pocket.outbound.entity.JpaUser;
import com.pocket.outbound.repository.UserRepository;
import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SecurityException;
Expand All @@ -23,7 +26,6 @@
import java.util.Collection;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.pocket.core.exception.jwt.SecurityErrorCode.INVALID_TOKEN;
Expand All @@ -41,20 +43,20 @@ public class JwtUtil {
private final Long accessExpMs;
private final Long refreshExpMs;
private final RedisUtil redisUtil;
private final UserAdapter userAdapter;
private final UserRepository userRepository;

public JwtUtil(
@Value("${security.jwt.secret}") String secret,
@Value("${security.jwt.token.access-expiration-time}") Long access,
@Value("${security.jwt.token.refresh-expiration-time}") Long refresh,
RedisUtil redis,
UserAdapter userAdapter) {
UserRepository userRepository) {

secretKey = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
accessExpMs = access;
refreshExpMs = refresh;
redisUtil = redis;
this.userAdapter = userAdapter;
this.userRepository = userRepository;
}

public String createJwtAccessToken(String email, String subId) {
Expand Down Expand Up @@ -112,10 +114,17 @@ public Authentication resolveToken(String token) {
Collection<SimpleGrantedAuthority> authorities = Stream.of(
String.valueOf(claims.get(AUTHORITIES)).split(","))
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
.toList();

UserInfoDTO userInfo = userAdapter.loadUserInfoByEmail(getEmail(token));
return new UsernamePasswordAuthenticationToken(userInfo, token, authorities);
final JpaUser user = findUser(getEmail(token));
UserInfoDTO infoDTO = new UserInfoDTO(user.getUser().getName(), user.getUser().getEmail(), user.getUser().getPicture());

return new UsernamePasswordAuthenticationToken(infoDTO, token, authorities);
}

private JpaUser findUser(String email) {
return userRepository.findByUserEmail(email)
.orElseThrow(() -> new UserCustomException(UserErrorCode.NO_USER_INFO));
}

public String resolveAccessToken(HttpServletRequest request) {
Expand Down
Loading