-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #6 from GSM-MSG/feature/5-google-oauth2-login
🔀 :: google oauth2 로그인
- Loading branch information
Showing
33 changed files
with
827 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
src/main/java/com/gcms/v3/domain/auth/exception/UserNotFoundException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.gcms.v3.domain.auth.exception; | ||
|
||
import com.gcms.v3.global.error.BasicException; | ||
import com.gcms.v3.global.error.ErrorCode; | ||
|
||
public class UserNotFoundException extends BasicException { | ||
public UserNotFoundException() { | ||
super(ErrorCode.USER_NOT_FOUND); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/main/java/com/gcms/v3/domain/auth/presentation/AuthController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.gcms.v3.domain.auth.presentation; | ||
|
||
import com.gcms.v3.domain.auth.presentation.data.request.SignInRequestDto; | ||
import com.gcms.v3.domain.auth.presentation.data.response.TokenInfoResponseDto; | ||
import com.gcms.v3.domain.auth.service.SignInService; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
@RequiredArgsConstructor | ||
@RestController | ||
@RequestMapping("/v3/auth") | ||
public class AuthController { | ||
|
||
private final SignInService signInService; | ||
|
||
@PostMapping | ||
public ResponseEntity<TokenInfoResponseDto> signIn (@RequestBody SignInRequestDto signInRequestDto) { | ||
TokenInfoResponseDto res = signInService.execute(signInRequestDto); | ||
return ResponseEntity.ok(res); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
src/main/java/com/gcms/v3/domain/auth/presentation/data/request/SignInRequestDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.gcms.v3.domain.auth.presentation.data.request; | ||
|
||
public record SignInRequestDto ( | ||
String code | ||
){ | ||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/com/gcms/v3/domain/auth/presentation/data/response/TokenInfoResponseDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.gcms.v3.domain.auth.presentation.data.response; | ||
|
||
import lombok.Builder; | ||
|
||
import java.time.LocalDateTime; | ||
|
||
@Builder | ||
public record TokenInfoResponseDto( | ||
String accessToken, | ||
String refreshToken, | ||
LocalDateTime accessTokenExpiresIn, | ||
LocalDateTime refreshTokenExpiresIn | ||
) { | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/com/gcms/v3/domain/auth/service/SignInService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.gcms.v3.domain.auth.service; | ||
|
||
import com.gcms.v3.domain.auth.presentation.data.request.SignInRequestDto; | ||
import com.gcms.v3.domain.auth.presentation.data.response.TokenInfoResponseDto; | ||
|
||
public interface SignInService { | ||
TokenInfoResponseDto execute(SignInRequestDto signInRequestDto); | ||
} |
58 changes: 58 additions & 0 deletions
58
src/main/java/com/gcms/v3/domain/auth/service/impl/SignInServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.gcms.v3.domain.auth.service.impl; | ||
|
||
import com.gcms.v3.domain.auth.presentation.data.request.SignInRequestDto; | ||
import com.gcms.v3.domain.auth.presentation.data.response.TokenInfoResponseDto; | ||
import com.gcms.v3.domain.auth.service.SignInService; | ||
import com.gcms.v3.domain.user.domain.entity.User; | ||
import com.gcms.v3.domain.user.domain.entity.UserRole; | ||
import com.gcms.v3.domain.user.domain.enums.Authority; | ||
import com.gcms.v3.domain.user.domain.repository.UserRepository; | ||
import com.gcms.v3.domain.user.domain.repository.UserRoleRepository; | ||
import com.gcms.v3.global.oauth2.GoogleOAuth2UserInfo; | ||
import com.gcms.v3.global.oauth2.OAuth2Service; | ||
import com.gcms.v3.global.security.jwt.JwtTokenProvider; | ||
import jakarta.transaction.Transactional; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@Transactional(rollbackOn = Exception.class) | ||
@RequiredArgsConstructor | ||
public class SignInServiceImpl implements SignInService { | ||
|
||
private final OAuth2Service oAuth2Service; | ||
private final UserRepository userRepository; | ||
private final JwtTokenProvider jwtTokenProvider; | ||
private final UserRoleRepository userRoleRepository; | ||
|
||
public TokenInfoResponseDto execute(SignInRequestDto signInRequestDto) { | ||
String accessToken = oAuth2Service.requestAccessToken(signInRequestDto.code()); | ||
GoogleOAuth2UserInfo googleOAuth2UserInfo = oAuth2Service.requestUserInfo(accessToken); | ||
|
||
User user = userRepository.findByEmail(googleOAuth2UserInfo.getEmail()) | ||
.orElseGet(() -> toEntity(googleOAuth2UserInfo)); | ||
|
||
return jwtTokenProvider.generateToken(user.getEmail()); | ||
} | ||
|
||
private User toEntity(GoogleOAuth2UserInfo googleOAuth2UserInfo) { | ||
User user = User.builder() | ||
.name(googleOAuth2UserInfo.getName()) | ||
.email(googleOAuth2UserInfo.getEmail()) | ||
.build(); | ||
|
||
userRepository.save(user); | ||
saveAuthority(user); | ||
return user; | ||
} | ||
|
||
private void saveAuthority(User user) { | ||
UserRole userRole = UserRole.builder() | ||
.user(user) | ||
.authority(Authority.ROLE_STUDENT) | ||
.build(); | ||
|
||
userRoleRepository.save(userRole); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
src/main/java/com/gcms/v3/domain/user/domain/repository/UserRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.gcms.v3.domain.user.domain.repository; | ||
|
||
import com.gcms.v3.domain.user.domain.entity.User; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
import java.util.Optional; | ||
|
||
public interface UserRepository extends JpaRepository<User, byte[]> { | ||
Optional<User> findByEmail(String email); | ||
} |
11 changes: 11 additions & 0 deletions
11
src/main/java/com/gcms/v3/domain/user/domain/repository/UserRoleRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.gcms.v3.domain.user.domain.repository; | ||
|
||
import com.gcms.v3.domain.user.domain.entity.User; | ||
import com.gcms.v3.domain.user.domain.entity.UserRole; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
import java.util.List; | ||
|
||
public interface UserRoleRepository extends JpaRepository<UserRole, byte[]> { | ||
List<UserRole> findByUser(User user); | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/com/gcms/v3/global/error/BasicException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.gcms.v3.global.error; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
|
||
@AllArgsConstructor | ||
@Getter | ||
public class BasicException extends RuntimeException{ | ||
ErrorCode errorCode; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.gcms.v3.global.error; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import org.springframework.http.HttpStatus; | ||
|
||
|
||
@AllArgsConstructor | ||
@Getter | ||
public enum ErrorCode { | ||
|
||
INVALID_AUTH_TOKEN(HttpStatus.UNAUTHORIZED, "권한 정보가 없는 토큰입니다."), | ||
EXPIRED_TOKEN(HttpStatus.UNAUTHORIZED, "만료된 토큰입니다."), | ||
INVALID_TOKEN_TYPE(HttpStatus.UNAUTHORIZED, "유효하지 않은 토큰 타입입니다."), | ||
USER_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 유저를 찾을 수 없습니다."), | ||
|
||
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "서버 내부 에러"); | ||
|
||
private final HttpStatus httpStatus; | ||
private final String message; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.gcms.v3.global.error; | ||
|
||
import lombok.Builder; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseEntity; | ||
|
||
@Builder | ||
public record ErrorResponse( | ||
HttpStatus status, | ||
String message | ||
) { | ||
public static ResponseEntity<ErrorResponse> toResponseEntity(ErrorCode e){ | ||
return ResponseEntity | ||
.status(e.getHttpStatus()) | ||
.body(ErrorResponse.builder() | ||
.status(e.getHttpStatus()) | ||
.message(e.getMessage()) | ||
.build() | ||
); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
src/main/java/com/gcms/v3/global/error/GlobalExceptionHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.gcms.v3.global.error; | ||
|
||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.ControllerAdvice; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
|
||
@ControllerAdvice | ||
public class GlobalExceptionHandler { | ||
|
||
@ExceptionHandler(BasicException.class) | ||
protected ResponseEntity<ErrorResponse> handleCustomException(BasicException e) { | ||
return ErrorResponse.toResponseEntity(e.getErrorCode()); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
src/main/java/com/gcms/v3/global/oauth2/GoogleOAuth2UserInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.gcms.v3.global.oauth2; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
import java.util.Map; | ||
|
||
@Getter | ||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
@NoArgsConstructor | ||
public class GoogleOAuth2UserInfo { | ||
|
||
protected Map<String, Object> attributes; | ||
|
||
public GoogleOAuth2UserInfo(Map<String, Object> attributes) { | ||
this.attributes = attributes; | ||
} | ||
|
||
public String getId() { | ||
return (String) attributes.get("sub"); | ||
} | ||
|
||
public String getName() { | ||
return (String) attributes.get("name"); | ||
} | ||
|
||
public String getEmail() { | ||
return (String) attributes.get("email"); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/com/gcms/v3/global/oauth2/GoogleProperties.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.gcms.v3.global.oauth2; | ||
|
||
import lombok.Getter; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
@Getter | ||
public class GoogleProperties { | ||
@Value("${spring.security.oauth2.client.provider.google.token-uri}") | ||
private String tokenUri; | ||
|
||
@Value("${spring.security.oauth2.client.registration.google.client-id}") | ||
private String clientId; | ||
|
||
@Value("${spring.security.oauth2.client.registration.google.client-secret}") | ||
private String clientSecret; | ||
|
||
@Value("${spring.security.oauth2.client.provider.google.user-info-uri}") | ||
private String userInfoUri; | ||
|
||
@Value("${spring.security.oauth2.client.registration.google.redirect-uri}") | ||
private String redirectUri; | ||
|
||
public static final String GRANT_TYPE = "authorization_code"; | ||
} |
71 changes: 71 additions & 0 deletions
71
src/main/java/com/gcms/v3/global/oauth2/OAuth2Service.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package com.gcms.v3.global.oauth2; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.core.ParameterizedTypeReference; | ||
import org.springframework.http.*; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.util.LinkedMultiValueMap; | ||
import org.springframework.util.MultiValueMap; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
import java.net.URLDecoder; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.Map; | ||
|
||
import static com.gcms.v3.global.oauth2.GoogleProperties.GRANT_TYPE; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class OAuth2Service { | ||
|
||
private final GoogleProperties config; | ||
private final RestTemplate restTemplate; | ||
|
||
public String requestAccessToken(String code) { | ||
String decode = URLDecoder.decode(code, StandardCharsets.UTF_8); | ||
|
||
HttpHeaders httpHeaders = new HttpHeaders(); | ||
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | ||
|
||
MultiValueMap<String, String> body = new LinkedMultiValueMap<>(); | ||
body.add("client_id", config.getClientId()); | ||
body.add("client_secret", config.getClientSecret()); | ||
body.add("code", decode); | ||
body.add("redirect_uri", config.getRedirectUri()); | ||
body.add("grant_type", GRANT_TYPE); | ||
|
||
HttpEntity<?> request = new HttpEntity<>(body, httpHeaders); | ||
|
||
ResponseEntity<Map<String, String>> response = | ||
restTemplate.exchange( | ||
config.getTokenUri(), | ||
HttpMethod.POST, | ||
request, | ||
new ParameterizedTypeReference<>() { | ||
} | ||
); | ||
|
||
return response.getBody().get("access_token"); | ||
} | ||
|
||
|
||
public GoogleOAuth2UserInfo requestUserInfo(String accessToken) { | ||
HttpHeaders httpHeaders = new HttpHeaders(); | ||
httpHeaders.setContentType(MediaType.APPLICATION_JSON); | ||
httpHeaders.setBearerAuth(accessToken); | ||
|
||
MultiValueMap<String, String> body = new LinkedMultiValueMap<>(); | ||
|
||
HttpEntity<?> request = new HttpEntity<>(body, httpHeaders); | ||
|
||
ResponseEntity<Map<String, Object>> response = | ||
restTemplate.exchange( | ||
config.getUserInfoUri(), | ||
HttpMethod.GET, | ||
request, | ||
new ParameterizedTypeReference<>() {} | ||
); | ||
|
||
return new GoogleOAuth2UserInfo(response.getBody()); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/com/gcms/v3/global/oauth2/config/ClientConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.gcms.v3.global.oauth2.config; | ||
|
||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
@Configuration | ||
public class ClientConfig { | ||
@Bean | ||
public RestTemplate restTemplate() { | ||
return new RestTemplate(); | ||
} | ||
} |
Oops, something went wrong.