Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,23 @@
import com.ikdaman.domain.auth.model.AuthReq;
import com.ikdaman.domain.auth.model.AuthRes;
import com.ikdaman.domain.auth.service.AuthService;
import com.ikdaman.domain.auth.service.OAuthService;
import com.ikdaman.domain.auth.service.SocialAuthService;
import com.ikdaman.global.auth.model.Tokens;
import com.ikdaman.global.exception.BaseException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Map;
import java.util.UUID;

import static com.ikdaman.global.exception.ErrorCode.INVALID_SOCIAL_PROVIDER;

@RestController
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {

private final Map<String, OAuthService> socialLoginServices;
private final SocialAuthService socialAuthService;
private final AuthService authService;

/**
Expand All @@ -36,13 +32,7 @@ public class AuthController {
public ResponseEntity<AuthRes> socialLogin(@RequestBody AuthReq dto,
@RequestHeader("social-token") String socialToken) {

String provider = dto.getProvider().toLowerCase();
OAuthService oAuthService = socialLoginServices.get(provider);
if (oAuthService == null) {
throw new BaseException(INVALID_SOCIAL_PROVIDER);
}

AuthRes res = oAuthService.login(dto, socialToken);
AuthRes res = socialAuthService.login(dto, socialToken);

HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", res.getAccessToekn());
Expand Down
117 changes: 0 additions & 117 deletions src/main/java/com/ikdaman/domain/auth/service/GoogleAuthService.java

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,74 @@
import com.ikdaman.domain.auth.model.AuthReq;
import com.ikdaman.domain.auth.model.AuthRes;
import com.ikdaman.domain.member.entity.Member;
import com.ikdaman.global.auth.enumerate.Provider;
import com.ikdaman.domain.member.repository.MemberRepository;
import com.ikdaman.domain.member.service.MemberService;
import com.ikdaman.global.auth.client.ClientNaver;
import com.ikdaman.global.auth.token.AuthToken;
import com.ikdaman.global.auth.token.AuthTokenProvider;
import com.ikdaman.global.exception.BaseException;
import com.ikdaman.global.util.RandomNickname;
import com.ikdaman.global.util.RedisService;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.ikdaman.global.exception.ErrorCode.NOT_MATCH_TOKEN_PROVIDER;

@Service("naver")
/**
* 통합 소셜 로그인 서비스
*/
@Service
@RequiredArgsConstructor
public class NaverAuthService implements OAuthService {
@Transactional
public class SocialAuthService implements SocialService {

private final ClientNaver clientNaver;
private final AuthTokenProvider authTokenProvider;
private final MemberService memberService;
private final SocialTokenValidator tokenValidator;
private final MemberRepository memberRepository;
private final RedisService redisService;
private final MemberService memberService;
private final RandomNickname randomNickname;
private final AuthTokenProvider authTokenProvider;
private final RedisService redisService;

@Value("${auth.refresh-token-validity}")
private long refreshExpiry; // RefreshToken 만료일

@Override
@Transactional
public AuthRes login(AuthReq dto, String socialAccessToken) {
public AuthRes login(AuthReq req, String socialToken) {

// 1. Provider 문자열 → Enum 변환
Provider provider = Provider.from(req.getProvider());

// 1. 소셜 accessToken을 통해 Naver userId 가져오기
String checkProviderId = clientNaver.getUserData(socialAccessToken);
// 2. 토큰 검증 및 providerId(sub) 추출
String providerIdFromToken = tokenValidator.validate(provider, socialToken);

// 2. 요청으로 들어온 providerId와 비교해서 검증
if (!dto.getProviderId().equals(checkProviderId)) throw new BaseException(NOT_MATCH_TOKEN_PROVIDER);
// 3. 요청의 providerId와 토큰에서 추출한 providerId 일치 검증
if (!req.getProviderId().equals(providerIdFromToken)) throw new BaseException(NOT_MATCH_TOKEN_PROVIDER);

// 3. 기존 회원 조회
Member member = memberRepository.findBySocialTypeAndProviderId(Member.SocialType.NAVER, checkProviderId)
// 4. 회원 조회(없으면 생성)
Member member = memberRepository
.findBySocialTypeAndProviderId(Member.SocialType.valueOf(provider.name()), providerIdFromToken)
.orElseGet(() -> {
String nickname;
do {
nickname = randomNickname.generate();
} while (!memberService.isAvailableNickname(nickname)); // 닉네임 중복되면 다시 생성

// 유저 정보 저장
// 신규 회원 저장
Member newMember = Member.builder()
.socialType(Member.SocialType.NAVER)
.providerId(checkProviderId)
.socialType(Member.SocialType.valueOf(provider.name()))
.providerId(providerIdFromToken)
.nickname(nickname)
.build();
return memberRepository.save(newMember);
});

// 3. 신규 토큰 생성 및 저장
AuthToken accessToken = authTokenProvider.createUserAppToken(String.valueOf(member.getMemberId()));
AuthToken refreshToken = authTokenProvider.createRefreshToken(String.valueOf(member.getMemberId()));
redisService.setValuesWithTimeout(String.valueOf(member.getMemberId()), refreshToken.getToken(), refreshExpiry);
// 5. 토큰 발급 및 리프레시 토큰 Redis 저장
String key = String.valueOf(member.getMemberId());
AuthToken accessToken = authTokenProvider.createUserAppToken(key);
AuthToken refreshToken = authTokenProvider.createRefreshToken(key);
redisService.setValuesWithTimeout(key, refreshToken.getToken(), refreshExpiry);

return AuthRes.builder()
.accessToekn(accessToken.getToken())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
import com.ikdaman.domain.auth.model.AuthReq;
import com.ikdaman.domain.auth.model.AuthRes;

public interface OAuthService {
public interface SocialService {
AuthRes login(AuthReq dto, String socialToken);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.ikdaman.domain.auth.service;

import com.ikdaman.global.auth.enumerate.Provider;
import com.ikdaman.global.auth.client.SocialTokenClient;
import com.ikdaman.global.exception.BaseException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Map;

import static com.ikdaman.global.exception.ErrorCode.INVALID_SOCIAL_PROVIDER;

/**
* Provider에 맞는 SocialTokenClient를 찾아 토큰을 검증하고 providerId를 추출
*/
@Service
@RequiredArgsConstructor
public class SocialTokenValidator {

private final Map<String, SocialTokenClient> clients;

public String validate(Provider provider, String token) {
SocialTokenClient client = clients.values().stream()
.filter(c -> c.provider() == provider)
.findFirst().orElse(null);
if (client == null) throw new BaseException(INVALID_SOCIAL_PROVIDER);
return client.extractProviderId(token);
}
}
Loading