Skip to content

Commit

Permalink
임시
Browse files Browse the repository at this point in the history
  • Loading branch information
70825 committed Jul 25, 2023
1 parent bbce2e7 commit 5700df6
Show file tree
Hide file tree
Showing 15 changed files with 550 additions and 0 deletions.
3 changes: 3 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ repositories {
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
runtimeOnly 'com.mysql:mysql-connector-j'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.rest-assured:rest-assured:4.4.0'
Expand Down
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 backend/src/main/java/com/funeat/auth/dto/KakaoTokenDto.java
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 backend/src/main/java/com/funeat/auth/dto/KakaoUserInfoDto.java
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 backend/src/main/java/com/funeat/auth/dto/LoginRequest.java
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 backend/src/main/java/com/funeat/auth/dto/TokenResponse.java
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 backend/src/main/java/com/funeat/auth/dto/UserInfoDto.java
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 backend/src/main/java/com/funeat/auth/service/AuthService.java
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);
});
}
}
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));
}
}
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 {
}
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;
}
}
Loading

0 comments on commit 5700df6

Please sign in to comment.