[리펙토링] 간편로그인(2)

윤재환·2025년 1월 23일

최근 간편로그인을 리펙토링 하여 OAuth2.0 표준에 맞춰 작성했습니다.

하지만 이후 구글,네이버 를 추가하다보면 유지보수에 있어서 코드가 많이 복잡해지기 때문에 유지보수를 위해 다시 리펙토링을 결심했습니다.

먼저 기존 코드를 보겠습니다.

 try {
        // 카카오 인증 처리
        if ("kakao".equals(oauthClientName)) {
            userId = "kakao_" + oAuth2User.getAttributes().get("id");

            // 데이터베이스에서 사용자 정보 조회
            userEntity = userRepository.findByUId(userId);

            if (userEntity == null) {
                // 새로운 사용자 생성 및 저장
                UserEntity newUser = new UserEntity();
                newUser.setUMail((String) oAuth2User.getAttributes().getOrDefault("kakao_account.email", ""));
                newUser.setUName((String) oAuth2User.getAttributes().getOrDefault("properties.nickname", "Unknown"));
                newUser.setURegister(LocalDate.now());
                newUser.setUPw(""); // 비밀번호는 빈 값으로 설정
                newUser.setUPofile((String) oAuth2User.getAttributes().getOrDefault("properties.profile_image", ""));
                newUser.setUBirth(""); // 생일 정보는 비워둠
                newUser.setUTel(""); // 전화번호 정보도 비워둠
                newUser.setUId(userId);

                // 데이터베이스에 사용자 저장
                userEntity = userRepository.save(newUser);
            }

            // 세션에 사용자 ID 저장
            request.getSession().setAttribute("UId", userEntity.getUId());
        }

    } catch (Exception e) {
        OAuth2Error error = new OAuth2Error("invalid_token", "Failed to process OAuth2 login", null);
        throw new OAuth2AuthenticationException(error, e.getMessage());
    }

기존 코드를 보면 우선 잘 정리는 되어있지만 다른 플랫폼(구글,네이버 등)의 추가가 어렵고 코드를 한 눈에 알아보기 어렵다. 또한 다른 플랫폼이 추가될 시, 코드가 길어질 가능성이 매우 높습니다.

우선 한 개의 서비스에서 동작하는 것을 두개로 나누고, 하나는 플랫폼만 판단하여 세션에 저장하는 기능과, 다른 하나는 실제 플랫폼에 맞는 로그인 로직을 실행하는 파일이다.

OAuth2UserServiceImplement.java

//
try {
			switch (oauthClientName) {

			case "kakao":
				userId = "kakao_" + oAuth2User.getAttributes().get("id");
				userEntity = oAuthLoginService.KakaoLogin(oAuth2User, userId);
				session.getSession().setAttribute("UId", userEntity.getUId());
                break;
			}
			
		} catch (

		Exception e) {
			OAuth2Error error = new OAuth2Error("invalid_token", "Failed to process OAuth2 login", null);
			throw new OAuth2AuthenticationException(error, e.getMessage());
		}

if문을 switch로 변환

if문으로 조건문을 보기 보다는
switch문으로 플랫폼 이름으로 판별하면 코드 가독성을 높혔습니다.

로그인 로직 분리

로그인 로직은 서비스에서 관리하고 플랫폼 판별은 컨트롤러에서 작성해서 코드 가독성을 높혔습니다.

OAuthLoginService.java

@Service
public class OAuthLoginService {

	@Autowired
	private UserRepository userRepository;

	public UserEntity KakaoLogin(OAuth2User oAuth2User, String userId) {

		UserEntity userEntity = new UserEntity();

		userEntity = userRepository.findByUId(userId);

		if (userEntity == null) {

			UserEntity newUser = new UserEntity();

			newUser.setUMail((String) oAuth2User.getAttributes().getOrDefault("kakao_account.email", ""));
			newUser.setUName((String) oAuth2User.getAttributes().getOrDefault("properties.nickname", "Unknown"));
			newUser.setURegister(LocalDate.now());
			newUser.setUPw(""); // 비밀번호는 빈 값으로 설정
			newUser.setUPofile((String) oAuth2User.getAttributes().getOrDefault("properties.profile_image", ""));
			newUser.setUBirth(""); // 생일 정보는 비워둠
			newUser.setUTel(""); // 전화번호도 비워둠
			newUser.setUId(userId);

			userEntity = userRepository.save(newUser);
		}
		return userEntity;
	}
}

로그인 로직 구현

각 풀랫폼마다 불러오는 값의 이름이 다르기 때문에 해당하는 각각 따로 생성 합니다.

결과

  1. 문제: 다른 플랫폼 추가 시, 코드 추가시 코드 복잡해진다.

    해결: 플랫폼을 판별하고 세션에 저장하는 컨트롤러와, 실제 로그인 로직은 실행시키는서비스 로직을 분리하였다.

profile
백엔드 개발에 관심있는 1인

0개의 댓글