[트러블슈팅] 간편로그인

윤재환·2025년 1월 23일

문제

문제 :결과적으로는 로그인은 성공했지만 해당 값들은 제대로 가져오지 못했습니다.

과정

플랫폼별 데이터 구조를 이해하고, 이를 표준화된 형태로 변환하여 하나의 메서드로 처리할 수 있도록 설계했습니다.

package com.my.interrior.common;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;

import com.my.interrior.client.user.UserEntity;
import com.my.interrior.client.user.UserRepository;

@Service
public class OAuthLoginService {

	@Autowired
	private UserRepository userRepository;

	public UserEntity SNSLogin(OAuth2User oAuth2User, String platform) {
		
		Map<String, Object> standardizedAttributes = extractAttributes(oAuth2User.getAttributes(), platform);
		
		String userId = (String) standardizedAttributes.get("userId");
		
		UserEntity userEntity = userRepository.findByUId(userId);
		
		if (userEntity == null) {
			userEntity = new UserEntity();
			userEntity.setUId(userId);
			userEntity.setUMail((String) standardizedAttributes.getOrDefault("email", ""));
            userEntity.setUName((String) standardizedAttributes.getOrDefault("nickname", "Unknown"));
            userEntity.setUPofile((String) standardizedAttributes.getOrDefault("profile_image", ""));
            userEntity.setURegister(LocalDate.now());
            //값을 가져오지 못하는거는 빈문자열로 저장
            userEntity.setUBirth("");
            userEntity.setUPw("");
            userEntity.setUTel("");
            userRepository.save(userEntity);
		}
		
		return userEntity;
	}
	
	
	//받아온 데이터를 사용할수 있게 가공
	@SuppressWarnings("unchecked")
	private Map<String, Object> extractAttributes(Map<String, Object> attributes, String platform) {
	    Map<String, Object> standardizedAttributes = new HashMap<>();

	    if ("kakao".equals(platform)) {
	    	//카카오 계정 정보 추출
	        Map<String, Object> kakaoAccount = (Map<String, Object>) attributes.get("kakao_account");
	        Map<String, Object> profile = kakaoAccount != null ? (Map<String, Object>) kakaoAccount.get("profile") : null;

	        //표준화된 데이터 맵에 추가
	        standardizedAttributes.put("email", kakaoAccount != null ? kakaoAccount.get("email") : "");
	        standardizedAttributes.put("nickname", profile != null ? profile.get("nickname") : "Unknown");
	        standardizedAttributes.put("profile_image", profile != null ? profile.get("profile_image_url") : "");
	        standardizedAttributes.put("userId", platform.toLowerCase() + "_" + attributes.get("id")); // 사용자 ID 추가
	    } else if ("naver".equals(platform)) {
	    	//네이버 계정 정보 추출
	        Map<String, Object> response = (Map<String, Object>) attributes.get("response");
	        
	        standardizedAttributes.put("email", response != null ? response.get("email") : "");
	        standardizedAttributes.put("nickname", response != null ? response.get("nickname") : "Unknown");
	        standardizedAttributes.put("profile_image", response != null ? response.get("profile_image") : "");
	        standardizedAttributes.put("userId", platform.toLowerCase() + "_" + (response != null ? response.get("id") : "")); // 사용자 ID 추가
	    } else if ("google".equals(platform)) {
	    	//구글 계정 정보 추출
	        standardizedAttributes.put("email", attributes.get("email"));
	        standardizedAttributes.put("nickname", attributes.get("name"));
	        standardizedAttributes.put("profile_image", attributes.get("picture"));
	        standardizedAttributes.put("userId", platform.toLowerCase() + "_" + attributes.get("sub")); // 사용자 ID 추가
	    } else {
	        throw new IllegalArgumentException("지원되지 않는 플랫폼: " + platform);
	    }
	    return standardizedAttributes;
	}
}

플랫폼마다 데이터를 통일성있게 가공을 했으며
추가적으로 플랫폼 로그인을 확장할때 해당 메서드에 로직을 추가하면 간단하게 확장을 할 수 있습니다.

public UserEntity SNSLogin(OAuth2User oAuth2User, String platform) {
		
		Map<String, Object> standardizedAttributes = extractAttributes(oAuth2User.getAttributes(), platform);
		
		String userId = (String) standardizedAttributes.get("userId");
		
		UserEntity userEntity = userRepository.findByUId(userId);
		
		if (userEntity == null) {
			userEntity = new UserEntity();
			userEntity.setUId(userId);
			userEntity.setUMail((String) standardizedAttributes.getOrDefault("email", ""));
            userEntity.setUName((String) standardizedAttributes.getOrDefault("nickname", "Unknown"));
            userEntity.setUPofile((String) standardizedAttributes.getOrDefault("profile_image", ""));
            userEntity.setURegister(LocalDate.now());
            //값을 가져오지 못하는거는 빈문자열로 저장
            userEntity.setUBirth("");
            userEntity.setUPw("");
            userEntity.setUTel("");
            userRepository.save(userEntity);
		}
		
		return userEntity;
	}

이후 값을 통일화 했으니 여러개의 매서드를 만들기보다는 하나의 메서드를 이용해서 로그인을 하는 방법을 만들었습니다.

결과

문제 : 플랫폼마다 가져오는 데이터의 값이 다르며, 데이터를 가공을 하지 않아 값을 가져오지 못함
해결 : 받아온 데이터 값들을 통일성 있게 가공을 했으며 하나의 메서드로 로그인, 회원가입을 진행

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

0개의 댓글