-
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.
- Loading branch information
Showing
15 changed files
with
550 additions
and
0 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
25 changes: 25 additions & 0 deletions
25
backend/src/main/java/com/funeat/auth/controller/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,25 @@ | ||
package com.funeat.auth.controller; | ||
|
||
import com.funeat.auth.dto.TokenResponse; | ||
import com.funeat.auth.service.AuthService; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
public class AuthController { | ||
|
||
private final AuthService authService; | ||
|
||
public AuthController(final AuthService authService) { | ||
this.authService = authService; | ||
} | ||
|
||
@GetMapping("/login/oauth2/code/kakao") | ||
public ResponseEntity<TokenResponse> kakaoLogin(@RequestParam("code") final String code) { | ||
final TokenResponse response = authService.loginWithKakao(code); | ||
|
||
return ResponseEntity.ok(response); | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
backend/src/main/java/com/funeat/auth/dto/KakaoTokenDto.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,53 @@ | ||
package com.funeat.auth.dto; | ||
|
||
import com.fasterxml.jackson.annotation.JsonCreator; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
|
||
public class KakaoTokenDto { | ||
|
||
private final String accessToken; | ||
private final String tokenType; | ||
private final String refreshToken; | ||
private final String expiresIn; | ||
private final String scope; | ||
private final String refreshTokenExpiresIn; | ||
|
||
@JsonCreator | ||
public KakaoTokenDto(@JsonProperty("access_token") final String accessToken, | ||
@JsonProperty("token_type") final String tokenType, | ||
@JsonProperty("refresh_token") final String refreshToken, | ||
@JsonProperty("expires_in") final String expiresIn, | ||
@JsonProperty("scope") final String scope, | ||
@JsonProperty("refresh_token_expires_in") final String refreshTokenExpiresIn) { | ||
this.accessToken = accessToken; | ||
this.tokenType = tokenType; | ||
this.refreshToken = refreshToken; | ||
this.expiresIn = expiresIn; | ||
this.scope = scope; | ||
this.refreshTokenExpiresIn = refreshTokenExpiresIn; | ||
} | ||
|
||
public String getAccessToken() { | ||
return accessToken; | ||
} | ||
|
||
public String getTokenType() { | ||
return tokenType; | ||
} | ||
|
||
public String getRefreshToken() { | ||
return refreshToken; | ||
} | ||
|
||
public String getExpiresIn() { | ||
return expiresIn; | ||
} | ||
|
||
public String getScope() { | ||
return scope; | ||
} | ||
|
||
public String getRefreshTokenExpiresIn() { | ||
return refreshTokenExpiresIn; | ||
} | ||
} |
82 changes: 82 additions & 0 deletions
82
backend/src/main/java/com/funeat/auth/dto/KakaoUserInfoDto.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,82 @@ | ||
package com.funeat.auth.dto; | ||
|
||
import com.fasterxml.jackson.annotation.JsonCreator; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
|
||
public class KakaoUserInfoDto { | ||
|
||
private final Long id; | ||
private final KakaoAccount kakaoAccount; | ||
|
||
@JsonCreator | ||
public KakaoUserInfoDto(@JsonProperty("id") final Long id, | ||
@JsonProperty("kakao_account") final KakaoAccount kakaoAccount) { | ||
this.id = id; | ||
this.kakaoAccount = kakaoAccount; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public KakaoAccount getKakaoAccount() { | ||
return kakaoAccount; | ||
} | ||
|
||
public static class KakaoAccount { | ||
|
||
private final KakaoProfile profile; | ||
private String email; | ||
private String ageRange; | ||
private String gender; | ||
|
||
@JsonCreator | ||
public KakaoAccount(@JsonProperty("profile") final KakaoProfile profile, | ||
@JsonProperty("email") String email, | ||
@JsonProperty("age_range") String ageRange, | ||
@JsonProperty("gender") String gender) { | ||
this.profile = profile; | ||
this.email = email; | ||
this.ageRange = ageRange; | ||
this.gender = gender; | ||
} | ||
|
||
public KakaoProfile getProfile() { | ||
return profile; | ||
} | ||
|
||
public String getEmail() { | ||
return email; | ||
} | ||
|
||
public String getAgeRange() { | ||
return ageRange; | ||
} | ||
|
||
public String getGender() { | ||
return gender; | ||
} | ||
} | ||
|
||
public static class KakaoProfile { | ||
|
||
private final String nickname; | ||
private final String profileImageUrl; | ||
|
||
@JsonCreator | ||
public KakaoProfile( | ||
@JsonProperty("nickname") final String nickname, | ||
@JsonProperty("profile_image_url") final String profileImageUrl) { | ||
this.nickname = nickname; | ||
this.profileImageUrl = profileImageUrl; | ||
} | ||
|
||
public String getNickname() { | ||
return nickname; | ||
} | ||
|
||
public String getProfileImageUrl() { | ||
return profileImageUrl; | ||
} | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
backend/src/main/java/com/funeat/auth/dto/LoginRequest.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.funeat.auth.dto; | ||
|
||
public class LoginRequest { | ||
|
||
private final Long id; | ||
|
||
public LoginRequest(final Long id) { | ||
this.id = id; | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
backend/src/main/java/com/funeat/auth/dto/TokenResponse.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.funeat.auth.dto; | ||
|
||
public class TokenResponse { | ||
|
||
private String accessToken; | ||
|
||
public TokenResponse(final String accessToken) { | ||
this.accessToken = accessToken; | ||
} | ||
|
||
public String getAccessToken() { | ||
return accessToken; | ||
} | ||
} |
56 changes: 56 additions & 0 deletions
56
backend/src/main/java/com/funeat/auth/dto/UserInfoDto.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,56 @@ | ||
package com.funeat.auth.dto; | ||
|
||
public class UserInfoDto { | ||
|
||
private final Long id; | ||
private final String nickname; | ||
private final String profileImageUrl; | ||
private String email; | ||
private String ageRange; | ||
private String gender; | ||
|
||
public UserInfoDto(final Long id, final String nickname, final String profileImageUrl, String email, | ||
String ageRange, String gender) { | ||
this.id = id; | ||
this.nickname = nickname; | ||
this.profileImageUrl = profileImageUrl; | ||
this.email = email; | ||
this.ageRange = ageRange; | ||
this.gender = gender; | ||
} | ||
|
||
public static UserInfoDto from(final KakaoUserInfoDto kakaoUserInfoDto) { | ||
return new UserInfoDto( | ||
kakaoUserInfoDto.getId(), | ||
kakaoUserInfoDto.getKakaoAccount().getProfile().getNickname(), | ||
kakaoUserInfoDto.getKakaoAccount().getProfile().getProfileImageUrl(), | ||
kakaoUserInfoDto.getKakaoAccount().getEmail(), | ||
kakaoUserInfoDto.getKakaoAccount().getAgeRange(), | ||
kakaoUserInfoDto.getKakaoAccount().getGender() | ||
); | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public String getNickname() { | ||
return nickname; | ||
} | ||
|
||
public String getProfileImageUrl() { | ||
return profileImageUrl; | ||
} | ||
|
||
public String getEmail() { | ||
return email; | ||
} | ||
|
||
public String getAgeRange() { | ||
return ageRange; | ||
} | ||
|
||
public String getGender() { | ||
return gender; | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
backend/src/main/java/com/funeat/auth/service/AuthService.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,49 @@ | ||
package com.funeat.auth.service; | ||
|
||
import com.funeat.auth.dto.TokenResponse; | ||
import com.funeat.auth.dto.UserInfoDto; | ||
import com.funeat.auth.util.JwtTokenProvider; | ||
import com.funeat.auth.util.KakaoPlatformUserProvider; | ||
import com.funeat.member.domain.Gender; | ||
import com.funeat.member.domain.Member; | ||
import com.funeat.member.persistence.MemberRepository; | ||
import java.util.Optional; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
public class AuthService { | ||
|
||
private final MemberRepository memberRepository; | ||
private final KakaoPlatformUserProvider kakaoPlatformUserProvider; | ||
private final JwtTokenProvider jwtTokenProvider; | ||
|
||
public AuthService(final MemberRepository memberRepository, | ||
final KakaoPlatformUserProvider kakaoPlatformUserProvider, | ||
final JwtTokenProvider jwtTokenProvider) { | ||
this.memberRepository = memberRepository; | ||
this.kakaoPlatformUserProvider = kakaoPlatformUserProvider; | ||
this.jwtTokenProvider = jwtTokenProvider; | ||
} | ||
|
||
public TokenResponse loginWithKakao(final String code) { | ||
final UserInfoDto userInfoDto = kakaoPlatformUserProvider.getPlatformUser(code); | ||
final Member member = findOrCreateMember(userInfoDto); | ||
final String token = jwtTokenProvider.createToken(member.getId().toString()); | ||
return new TokenResponse(token); | ||
} | ||
|
||
private Member findOrCreateMember(final UserInfoDto userInfoDto) { | ||
final String platformId = userInfoDto.getId().toString(); | ||
|
||
return memberRepository.findByPlatformId(platformId).orElseGet(() -> { | ||
final String nickname = userInfoDto.getNickname(); | ||
final String profileImage = userInfoDto.getProfileImageUrl(); | ||
final Integer age = 10; | ||
final Gender gender = Gender.valueOf(Optional.ofNullable(userInfoDto.getGender()) | ||
.orElse("male")); | ||
final String phoneNumber = "010-1234-1234"; | ||
final Member member = new Member(nickname, profileImage, age, gender, phoneNumber, platformId); | ||
return memberRepository.save(member); | ||
}); | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
backend/src/main/java/com/funeat/auth/util/AuthArgumentResolver.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,36 @@ | ||
package com.funeat.auth.util; | ||
|
||
import com.funeat.auth.dto.LoginRequest; | ||
import java.util.Objects; | ||
import javax.servlet.http.HttpServletRequest; | ||
import org.springframework.core.MethodParameter; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.bind.support.WebDataBinderFactory; | ||
import org.springframework.web.context.request.NativeWebRequest; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
import org.springframework.web.method.support.ModelAndViewContainer; | ||
|
||
@Component | ||
public class AuthArgumentResolver implements HandlerMethodArgumentResolver { | ||
|
||
private final JwtTokenProvider jwtTokenProvider; | ||
|
||
public AuthArgumentResolver(final JwtTokenProvider jwtTokenProvider) { | ||
this.jwtTokenProvider = jwtTokenProvider; | ||
} | ||
|
||
@Override | ||
public boolean supportsParameter(MethodParameter parameter) { | ||
return parameter.hasParameterAnnotation(AuthenticationPrincipal.class); | ||
} | ||
|
||
@Override | ||
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, | ||
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { | ||
final HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); | ||
final String token = AuthorizationExtractor.extract(Objects.requireNonNull(request)); | ||
final String id = jwtTokenProvider.getPayload(token); | ||
|
||
return new LoginRequest(Long.valueOf(id)); | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
backend/src/main/java/com/funeat/auth/util/AuthenticationPrincipal.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.funeat.auth.util; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Target(ElementType.PARAMETER) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface AuthenticationPrincipal { | ||
} |
30 changes: 30 additions & 0 deletions
30
backend/src/main/java/com/funeat/auth/util/AuthorizationExtractor.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,30 @@ | ||
package com.funeat.auth.util; | ||
|
||
import java.util.Enumeration; | ||
import javax.servlet.http.HttpServletRequest; | ||
|
||
public class AuthorizationExtractor { | ||
|
||
private static final String AUTHORIZATION = "Authorization"; | ||
private static final String BEARER_TYPE = "Bearer"; | ||
private static final String ACCESS_TOKEN_TYPE = AuthorizationExtractor.class.getSimpleName() + ".ACCESS_TOKEN_TYPE"; | ||
|
||
public static String extract(final HttpServletRequest request) { | ||
final Enumeration<String> headers = request.getHeaders(AUTHORIZATION); | ||
|
||
while (headers.hasMoreElements()) { | ||
final String value = headers.nextElement(); | ||
if ((value.toLowerCase().startsWith(BEARER_TYPE.toLowerCase()))) { | ||
String authHeaderValue = value.substring(BEARER_TYPE.length()).trim(); | ||
request.setAttribute(ACCESS_TOKEN_TYPE, value.substring(0, BEARER_TYPE.length()).trim()); | ||
final int commaIndex = authHeaderValue.indexOf(','); | ||
if (commaIndex > 0) { | ||
authHeaderValue = authHeaderValue.substring(0, commaIndex); | ||
} | ||
return authHeaderValue; | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
} |
Oops, something went wrong.