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 @@ -30,6 +30,7 @@ public enum AuthErrorCode implements BaseErrorCode {
*/
RECERTIFICATION_FAIL_USER_WITHDRAW_PENDING(HttpStatus.FORBIDDEN, "사용자가 탈퇴 대기중이기 때문에, 해당 토큰으로 재인증할 수 없습니다."),
RECERTIFICATION_FAIL_USER_WITHDRAWN(HttpStatus.FORBIDDEN, "사용자가 탈퇴했기 때문에, 해당 토큰으로 재인증할 수 없습니다."),
GOOGLE_JOIN_FAIL_USER_WITHDRAWN(HttpStatus.FORBIDDEN, "사용자가 탈퇴했기 때문에, 구글로 회원가입 할 수 없습니다."),

/**
* 401 UNAUTHORIZED: 인증되지 않음
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.List;
import java.util.Optional;

Expand All @@ -24,20 +23,10 @@ public interface AuthAccountRepository extends JpaRepository<AuthAccount, Long>
*/
@Query("SELECT a FROM AuthAccount a JOIN FETCH a.user " +
"WHERE a.hashedDeviceUid = :hashedDeviceUid AND a.provider = :provider")
Optional<AuthAccount> findByDeviceUidAndProvider(
Optional<AuthAccount> findByHashedDeviceUidAndProvider(
@Param("hashedDeviceUid") String hashedDeviceUid,
@Param("provider") Provider provider
);
/**
* HashedDeviceUid & Provider로 AuthAccount 객체를 찾는 함수
* @param hashedDeviceUid String
* @param provider Provider
* @return Optional<AuthAccount></AuthAccount>
*/
@Query("select a from AuthAccount a " +
"join fetch a.user u " +
"where a.hashedDeviceUid = :hashedDeviceUid and a.provider = :provider")
Optional<AuthAccount> findByHashedDeviceUidAndProvider(@Param("hashedDeviceUid") String hashedDeviceUid, @Param("provider") Provider provider);
/**
* 특정 유저의 특정 Provider 계정 조회 (Guest 계정 찾기용)
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import com.example.egobook_be.domain.terms.repository.UserTermRepository;
import com.example.egobook_be.domain.user.entity.Ability;
import com.example.egobook_be.domain.user.enums.RoleType;
import com.example.egobook_be.domain.user.enums.UserErrorCode;
import com.example.egobook_be.domain.user.enums.UserStatus;
import com.example.egobook_be.domain.user.repository.AbilityRepository;
import com.example.egobook_be.global.util.*;
Expand Down Expand Up @@ -99,8 +100,22 @@ public JwtTokenResDto registerGoogle(GoogleJoinReqDto reqDto){
* - Provider.GOOGLE과 조합하여 체크한다.
*/
String hashedGoogleSub = hashingUtil.hashingValue(googleSub);
if(authAccountRepository.existsByHashedDeviceUidAndProvider(hashedGoogleSub, Provider.GOOGLE)){
throw new CustomException(AuthErrorCode.ALREADY_REGISTERED_USER);
AuthAccount authAccount = authAccountRepository.findByHashedDeviceUidAndProvider(hashedGoogleSub, Provider.GOOGLE).orElse(null);
if(authAccount != null){
// (1) 기존에 가입된 계정이라면, User를 찾아서 삭제 대기중인지 확인한다
User user = authAccount.getUser();

// (2) 만약 삭제 대기 중인 경우라면 해당 계정의 상태를 ACTIVE로 변경하고, 토큰을 새로 발급한 뒤 Refresh Token Backup 테이블 & Redis 갱신 후 결과 반환
if(user.getStatus().equals(UserStatus.WITHDRAW_PENDING)){
log.info("[Google Join] 탈퇴 대기 중인 구글 사용자가 재 회원가입을 시도하였습니다.");
user.cancelWithDrawUser(); // 사용자 상태 복구
return processIssueTokens(user, authAccount, email);
}
// (3) 만약 사용자가 삭제 상태면 예외 throw
if(user.getStatus().equals(UserStatus.WITHDRAW)){
log.info("[Google Join] 탈퇴된 구글 사용자가 재 회원가입을 시도하였습니다.");
throw new CustomException(AuthErrorCode.GOOGLE_JOIN_FAIL_USER_WITHDRAWN);
}
}

/*
Expand All @@ -116,24 +131,29 @@ public JwtTokenResDto registerGoogle(GoogleJoinReqDto reqDto){
* - hashedDeviceUid 자리에 hashedGoogleSub를 저장한다.
* - recoverToken은 createAuthAccount 내부에서 초기값(null)으로 설정된다.
*/
AuthAccount authAccount = createAuthAccount(user, Provider.GOOGLE, hashedGoogleSub);
authAccount = createAuthAccount(user, Provider.GOOGLE, hashedGoogleSub);

// 5. Token을 발급 및 환경 세팅 수행
return processIssueTokens(user, authAccount, email);
}

// 5. 토큰 발급을 위한 UserDetails 생성
/** Token들을 발급하는 과정을 담은 함수 */
private JwtTokenResDto processIssueTokens(User user, AuthAccount authAccount, String email){
// 1. 토큰 발급을 위한 UserDetails 생성
CustomUserDetails userDetails = buildCustomUserDetails(user, authAccount);

/*
* 6. Access, Refresh Token 생성
* 2. Access, Refresh Token 생성
* - **주의**: Google은 Recover Token을 생성하지 않는다.
*/
TokenInfo accessTokenInfo = jwtUtil.createAccessToken(userDetails);
TokenInfo refreshTokenInfo = jwtUtil.createRefreshToken(userDetails);

// 7. Refresh Token을 Table, Redis에 저장하는 Process 수행
// 3. Refresh Token을 Table, Redis에 저장하는 Process 수행
processRefreshTokenSaving(user, authAccount, refreshTokenInfo);

/*
* 8. 클라이언트에게 토큰 반환
* 4. 클라이언트에게 토큰 반환
* - Google 로그인이므로 recoverToken은 null을 반환한다.
*/
return buildJwtTokenResDto(accessTokenInfo.token(), refreshTokenInfo.token(), null, email);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@ public void withdrawUser(Long purgeDurationInMs) {
this.notificationEnabled = false;
}

public void cancelWithDrawUser(){
this.status = UserStatus.ACTIVE;
this.deletedAt = null;
this.purgeAt = null;
this.dailyPraise = true;
this.notificationEnabled = true;
}

public void addInk(int amount) {
this.ink += amount;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,5 @@ List<User> findByNicknameContainingIgnoreCaseOrAccountCodeContainingIgnoreCase(
""")
List<Long> findAvailableReceivers(@Param("now") OffsetDateTime now, Pageable pageable);

Optional<User> findByEmail(String email);
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,8 @@ private List<Item> getInitItemList(){
* 5-3) Beach.png
*/
items.add(buildBackgroundItem("Default.png", 0));
items.add(buildBackgroundItem("Blossom.png", 0));
items.add(buildBackgroundItem("Beach.png", 0));
items.add(buildBackgroundItem("Blossom.png", 750));
items.add(buildBackgroundItem("Beach.png", 1000));

return items;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public UserDetails loadUserByUsername(String compositeKey) {
* - AuthAccountRepository에서 fetch join으로 영속성 컨텍스트에 User 정보까지 같이 가져온 상태이다.
* throw 해당 UID 기기를 찾을 수 없다는 예외
*/
AuthAccount authAccount = authAccountRepository.findByDeviceUidAndProvider(deviceUid, provider)
AuthAccount authAccount = authAccountRepository.findByHashedDeviceUidAndProvider(deviceUid, provider)
.orElseThrow(() -> new CustomException(AuthErrorCode.USER_NOT_FOUND));

/*
Expand Down
Loading