Skip to content

Commit

Permalink
Merge pull request #121 from kakao-tech-campus-2nd-step3/Weekly-10
Browse files Browse the repository at this point in the history
[Develop] 로그인 API - 프론트 로컬 오리진, 배포 오리진 환경 대응 로직 추가
  • Loading branch information
minsu-cnu authored Nov 9, 2024
2 parents 2dd8ea5 + b5ab5d4 commit b252e96
Show file tree
Hide file tree
Showing 13 changed files with 67 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2024-11-03T19:16:36+0900",
date = "2024-11-08T17:16:00+0900",
comments = "version: 1.5.3.Final, compiler: javac, environment: Java 21.0.3 (Eclipse Adoptium)"
)
@Component
Expand Down Expand Up @@ -60,7 +60,7 @@ public RecruitmentResponse toRecruitmentResponse(Recruitment recruitment, Recrui
String vietnameseTitle = null;
String companySize = null;
String area = null;
String salary = null;
Long salary = null;
String workDuration = null;
String workDays = null;
String workType = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2024-11-03T19:16:36+0900",
date = "2024-11-08T17:16:00+0900",
comments = "version: 1.5.3.Final, compiler: javac, environment: Java 21.0.3 (Eclipse Adoptium)"
)
@Component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
Expand Down Expand Up @@ -47,9 +48,12 @@ public AuthController(AuthService authService) {
@ApiResponse(responseCode = "500", description = "서버 내부 에러", content = @Content(mediaType = "application/json", schema = @Schema(implementation = ExceptionResponse.class)))
})
@PostMapping("/oauth")
public ResponseEntity<UserTypeResponse> login(@RequestBody CodeRequest codeRequest) {
public ResponseEntity<UserTypeResponse> login(@RequestBody CodeRequest codeRequest,
HttpServletRequest request) {
String referer = request.getHeader("Referer");

OAuthJwtResponse oAuthJwtResponse = authService.getOAuthToken(codeRequest,
GOOGLE_TOKEN_URI);
GOOGLE_TOKEN_URI, referer);
LoginResponse loginResponse = authService.registerOAuth(oAuthJwtResponse,
GOOGLE_USER_INFO_URI);

Expand Down
24 changes: 20 additions & 4 deletions src/main/java/team18/team18_be/auth/service/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public class AuthService {
public static final String AUTHORIZATION = "Authorization";
public static final String BEARER = "Bearer ";
public static final String ACCESS_TOKEN = "access_token";
public static final String LOCALHOST = "localhost";
private final AuthRepository authRepository;
private final GoogleProperty googleProperty;
private final RestClient restClient = RestClient.builder().build();
Expand All @@ -55,8 +56,10 @@ public AuthService(AuthRepository authRepository, GoogleProperty googleProperty)
this.googleProperty = googleProperty;
}

public OAuthJwtResponse getOAuthToken(CodeRequest codeRequest, String externalApiUri) {
LinkedMultiValueMap<String, String> requestBody = getRequestBody(codeRequest);
public OAuthJwtResponse getOAuthToken(CodeRequest codeRequest, String externalApiUri,
String referer) {
validateReferer(referer);
LinkedMultiValueMap<String, String> requestBody = getRequestBody(codeRequest, referer);

ResponseEntity<String> response = restClient.post()
.uri(URI.create(externalApiUri))
Expand Down Expand Up @@ -111,13 +114,20 @@ public void registerUserType(UserTypeRequest userTypeRequest, User user) {
authRepository.save(user.updateUserType(userTypeRequest.type()));
}

private LinkedMultiValueMap<String, String> getRequestBody(CodeRequest codeRequest) {
private LinkedMultiValueMap<String, String> getRequestBody(CodeRequest codeRequest,
String referer) {
LinkedMultiValueMap<String, String> requestBody = new LinkedMultiValueMap<>();
requestBody.add(AUTHORIZATION_CODE, codeRequest.code());
requestBody.add(CLIENT_ID, googleProperty.clientId());
requestBody.add(CLIENT_SECRET, googleProperty.clientSecret());
requestBody.add(REDIRECT_URI, googleProperty.redirectUri());
requestBody.add(GRANT_TYPE, googleProperty.grantType());

if (referer.contains(LOCALHOST)) {
requestBody.add(REDIRECT_URI, googleProperty.redirectUriLocal());
} else {
requestBody.add(REDIRECT_URI, googleProperty.redirectUriProd());
}

return requestBody;
}

Expand All @@ -139,4 +149,10 @@ private String getAccessToken(User user) {
.signWith(key)
.compact();
}

private void validateReferer(String referer) {
if (referer == null) {
throw new IllegalCallerException(ErrorMessage.NOT_FOUND_REFERER_IN_HEADER.getErrorMessage());
}
}
}
11 changes: 7 additions & 4 deletions src/main/java/team18/team18_be/config/CorsConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@
@Configuration
public class CorsConfig implements WebMvcConfigurer {

@Value("${front.origin}")
private String FRONT_ORIGIN;
@Value("${front.origin-local}")
private String FRONT_ORIGIN_LOCAL;

@Value("${front.origin-prod}")
private String FRONT_ORIGIN_PROD;

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins(FRONT_ORIGIN)
.allowedOrigins(FRONT_ORIGIN_LOCAL, FRONT_ORIGIN_PROD)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD")
.allowedHeaders("Authorization", "Content-Type")
.allowedHeaders("Authorization", "Content-Type", "Referer")
.exposedHeaders(HttpHeaders.LOCATION, HttpHeaders.AUTHORIZATION)
.allowCredentials(true)
.maxAge(1800);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
public record GoogleProperty(
String clientId,
String clientSecret,
String redirectUri,
String redirectUriLocal,
String redirectUriProd,
String grantType
) {

Expand Down
3 changes: 2 additions & 1 deletion src/main/java/team18/team18_be/exception/ErrorMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ public enum ErrorMessage {
GOOGLE_OAUTH_USER_INFO_ERROR_MESSAGE("구글 유저 정보 조회 중 에러가 발생하였습니다."),
OBJECT_MAPPER_ERROR_MESSAGE("JSON 파싱 오류가 발생하였습니다."),
NOT_FOUND_ACCESS_TOKEN_ERROR_MESSAGE("요청에 액세스 토큰이 존재하지 않습니다."),
ACCESS_TOKEN_EXPIRED_ERROR_MESSAGE("액세스 토큰이 만료되었습니다.");
ACCESS_TOKEN_EXPIRED_ERROR_MESSAGE("액세스 토큰이 만료되었습니다."),
NOT_FOUND_REFERER_IN_HEADER("헤더에 Referer가 없습니다.");

private final String errorMessage;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,11 @@ public ResponseEntity<ExceptionResponse> handleFileDownloadException(
ExceptionResponse exceptionResponse = new ExceptionResponse(e.getMessage());
return new ResponseEntity<>(exceptionResponse, HttpStatus.NOT_FOUND);
}

@ExceptionHandler(value = IllegalCallerException.class)
public ResponseEntity<ExceptionResponse> handleIllegalCallerException(
IllegalCallerException e) {
ExceptionResponse exceptionResponse = new ExceptionResponse(e.getMessage());
return new ResponseEntity<>(exceptionResponse, HttpStatus.BAD_REQUEST);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public ResumeAndApplyResponse findResumeById(Long resumeId, Long applyId) {
.orElseThrow(() -> new NoSuchElementException("해당하는 지원이 존재하지 않습니다."));
ApplicationForm applicationForm = applicationFormRepository.findByApply(apply)
.orElseThrow(() -> new NoSuchElementException("해당하는 지원이 존재하지 않습니다."));
return resumeMapper.toResumeAndApplyResponse(resume,applicationForm.getMotivation());
return resumeMapper.toResumeAndApplyResponse(resume, applicationForm.getMotivation());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ public ResponseEntity<SignResponse> findSign(@LoginUser User user) {

@Operation(summary = "회사등록")
@PostMapping(value = "/company", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Void> createCompany(@RequestPart("companyRequest") String companyRequestJson,
public ResponseEntity<Void> createCompany(
@RequestPart("companyRequest") String companyRequestJson,
@RequestPart MultipartFile logoImage, @LoginUser User user) {
System.out.println(companyRequestJson);
ObjectMapper objectMapper = new ObjectMapper();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public void setUp() {
public void testCreateApplicationForm() {
// Given
ApplicationFormRequest request = new ApplicationFormRequest("홍길동", "123 Street",
"01012345678","my_motivation");
"01012345678", "my_motivation");
Long recruitmentId = 1L;

when(applyRepository.save(any(Apply.class))).thenReturn(
Expand Down
14 changes: 9 additions & 5 deletions src/test/java/team18/team18_be/auth/service/AuthServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class AuthServiceTest {
static final String APPLICATION_TEST_PROPERTIES = "application-test.properties";
static final String OAUTH_GOOGLE_CLIENT_ID = "oauth.google.client-id";
static final String OAUTH_GOOGLE_CLIENT_SECRET = "oauth.google.client-secret";
static final String OAUTH_GOOGLE_REDIRECT_URI = "oauth.google.redirect-uri";
static final String OAUTH_GOOGLE_REDIRECT_URI_LOCAL = "oauth.google.redirect-uri-local";
static final String OAUTH_GOOGLE_REDIRECT_URI_PROD = "oauth.google.redirect-uri-prod";
static final String OAUTH_GOOGLE_GRANT_TYPE = "oauth.google.grant-type";
static final String JWT_SECRET = "jwt.secret";
static final String SECRET_KEY = "SECRET_KEY";
Expand All @@ -61,6 +62,8 @@ class AuthServiceTest {
static final String AUTHORIZATION_CODE = "authorization_code";
static final String OAUTH_ACCESS_TOKEN = "access_token";

static final String REFERER = "referer";

@InjectMocks
AuthService authService;

Expand Down Expand Up @@ -94,14 +97,15 @@ class AuthServiceTest {

String clientId = properties.getProperty(OAUTH_GOOGLE_CLIENT_ID);
String clientSecert = properties.getProperty(OAUTH_GOOGLE_CLIENT_SECRET);
String redirectUri = properties.getProperty(OAUTH_GOOGLE_REDIRECT_URI);
String redirectUriLocal = properties.getProperty(OAUTH_GOOGLE_REDIRECT_URI_LOCAL);
String redirectUriProd = properties.getProperty(OAUTH_GOOGLE_REDIRECT_URI_PROD);
String grantType = properties.getProperty(OAUTH_GOOGLE_GRANT_TYPE);
String secretKey = properties.getProperty(JWT_SECRET);

ReflectionTestUtils.setField(authService, SECRET_KEY, secretKey);

ReflectionTestUtils.setField(authService, GOOGLE_PROPERTY,
new GoogleProperty(clientId, clientSecert, redirectUri, grantType));
new GoogleProperty(clientId, clientSecert, redirectUriLocal, redirectUriProd, grantType));
}

@BeforeEach
Expand Down Expand Up @@ -139,7 +143,7 @@ class AuthServiceTest {
CodeRequest codeRequest = new CodeRequest(AUTHORIZATION_CODE);

// when
OAuthJwtResponse response = authService.getOAuthToken(codeRequest, mockServerUri);
OAuthJwtResponse response = authService.getOAuthToken(codeRequest, mockServerUri, REFERER);

// then
assertThat(response.accessToken()).isEqualTo(OAUTH_ACCESS_TOKEN);
Expand All @@ -153,7 +157,7 @@ class AuthServiceTest {
CodeRequest codeRequest = new CodeRequest(AUTHORIZATION_CODE);

// when, then
assertThatThrownBy(() -> authService.getOAuthToken(codeRequest, mockUri)).isInstanceOf(
assertThatThrownBy(() -> authService.getOAuthToken(codeRequest, mockUri, REFERER)).isInstanceOf(
OAuthLoginFailedException.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import static org.mockito.Mockito.when;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -86,11 +88,13 @@ public void testCreateCompany() {
@Test
public void testFindCompany() {
//given
when(companyRepository.findByUser(employer)).thenReturn(Optional.of(company));
List<Company> comapnys = new ArrayList<>();
comapnys.add(company);
when(companyRepository.findByUser(employer)).thenReturn(Optional.of(comapnys));
//when
CompanyResponse companyResponse = userInformationService.findCompany(employer);
List<CompanyResponse> companyResponse = userInformationService.findCompany(employer);
//then
assertEquals(company.getId(), companyResponse.CompanyId());
assertEquals(company.getId(), companyResponse.get(0).companyId());
}

@Test
Expand Down

0 comments on commit b252e96

Please sign in to comment.