개발공부/spring security & JWT 강의

[10강] 페이스북 로그인 완료

기억지기 개발자 2023. 11. 13. 23:34

🤍받은 인증 정보들을 코드에 기입해 주기

색깔에 맞춰서 각각 정보들을 기입해 주면 된다. 

실제 발급받은 화면
실제 코드 화면

 

🤍oauth에서 제공하는 규격에 맞게 요청 url을 작성한다.

OAuth2 클라이언트 애플리케이션에서 정의한 OAuth2 공급자(여기서는 Facebook)에 대한 인증을 시작하라는 요청을 나타내는 것이다!! 

( OAuth2 클라이언트의 구성에 따라 "facebook" 부분이 다른 OAuth2 공급자 이름으로 대체될 수 있다.)

 

 

🤍1차 테스트(?)로 요청을 해본다...!! (성공)

 

로그인을 하고 나면 다음 사진에 있는 과정을 거치게 된다.

(이 강의 이전에 작성해 놓은 코드가 작동을 하는 것이다 - oauth 로그인에 대한 처리를 다 해놓았기 때문에 바로 기본적인 정보가 따라온다.)

 

핑크색 박스의 내용을 보면 facebook이라고 찍혀있고, 페이스북에서 제공하는 정보(Attributes)는 초록 박스들과 같이 id, email, name 이렇게 3가지이다. 

 


그런데 여기서 작은 문제가 생긴다....‼️‼️‼️‼️

구글에서의 Id값은 sub라는 이름으로 오지만, 구글에서는 id라는 이름으로 오기 때문에 현재 코드에서는 페이스북으로 로그인을 진행하면 해당 값(providerId)이 null값이 나온다. 

구글로 로그인을 할 때는 코드를 

String providerId = oAuth2User.getAttribute("sub");

 

페이스북으로 로그인할 때는 코드를 

String providerId = oAuth2User.getAttribute("id");

 

이런 식으로 변경해 줘야 providerId에 null값이 들어가지 않고 정상작동을 한다는 소리이다. 

그런데 당연히~~ 그때마다 코드를 변경하는 것은 옳지 않은 방식이기 때문에 이 부분에 관하여 코드를 더 추가/수정해 볼 예정이다.


🤍해결을 위한 과정들..!! 

새로 만든 폴더,클래스 구조
OAuth의 데이터를 받아오는 인터페이스 정의

Attributes에 오는 데이터를 다루는 인터페이스인 셈이다.

 

왼쪽은 구글, 오른쪽은 페이스북을 위한 클래스~

핑크박스 부분이 이 클래스를 정의한 핵심적인 이유라고 할 수 있다. 

다르게 넘어오는 id 값을 받아오기 위해서 각각에 맞게 코드를 작성해 주었다.

 

@Service
public class PrincipalOauth2UserService extends DefaultOAuth2UserService {
    BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();

    @Autowired
    private UserRepository userRepository;

    private static final Logger log = LoggerFactory.getLogger(PrincipalOauth2UserService.class);

    @Override
    public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException{
        log.info("getClientRegistration : "+userRequest.getClientRegistration());
        log.info("getAccessToken : "+userRequest.getAccessToken().getTokenValue());

        OAuth2User oAuth2User = super.loadUser(userRequest);

        log.info("getAttributes : "+oAuth2User.getAttributes());

        OAuth2UserInfo oAuth2UserInfo = null;
        if(userRequest.getClientRegistration().getClientId().equals("google")) {
            System.out.println("--- 구글 로그인 요청 ---");
            oAuth2UserInfo = new GoogleUserInfo(oAuth2User.getAttributes());
        } else if(userRequest.getClientRegistration().getClientId().equals("facebook")) {
            System.out.println("--- 페이스북 로그인 요청 ---");
            oAuth2UserInfo = new GoogleUserInfo(oAuth2User.getAttributes());
        } else {
            System.out.println("우리는 구글과 페이스북만 지원합니다.");
        }

        String provider = oAuth2UserInfo.getProvider();
        String providerId = oAuth2UserInfo.getProviderId();
        String username = provider + "_" + providerId;
        String password = bCryptPasswordEncoder.encode("TemporaryPasswordKey");
        String email = oAuth2UserInfo.getEmail();
        String role = "ROLE_USER";

        User userentity = userRepository.findByUsername(username);
        if(userentity == null) {
            userentity = User.builder()
                    .username(username)
                    .password(password)
                    .email(email)
                    .role(role)
                    .provider(provider)
                    .providerId(providerId)
                    .build();
            userRepository.save(userentity);
        }
        return new PrincipalDetails(userentity, oAuth2User.getAttributes());
    }
}

PrincipalOauth2UserService의 코드도 이에 맞게 변경해 주었다.

매개변수로 들어오는 값의 userRequest.getClientRegistration().getClientId()의 값이 google인지 facebook인지를 판별하여 각각 맞는 코드를 작성하였다.

 

 

⭐느낀 점

말로만 듣던 소셜 로그인을 이렇게 구현해 보게 되어서 신기하다.

다르게 넘어오는 정보를 직접  console로 찍어서 확인도 해보고 그에 따라 코드로 적절하게 대응하는 것이 상당히 흥미롭다!! ^0^ 그런데 확실히 spring security 쪽이 별의별 인터페이스, 클래스들이 너무 많아서 어려운 감이 있다....

그런데 이 강의를 통해서 어려움의 허물을 한 겹은 벗긴 거 같아서 앞으로 더 열심히 해보고 싶다는 생각이 든다ㅎㅎ