ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • OAuth - 페이스북 로그인 (OAuth2UserInfo - 각각의 provider)
    스프링/스프링 시큐리티 2024. 1. 10. 20:06

    페이스북 로그인 구현도 구글과 비슷하게 진행된다. 페이스북 로그인 api 생성 페이지에서 앱을 만들어준 다음에 정보를 application.yml에 입력하면 된다.

     

     

    application.yml

    spring:
      security:
        oauth2:
          client:
            registration:
              google:
                client-id: 1031257684665-knkr9fbcoeud3gg55hc3kr47cd2n2g2q.apps.googleusercontent.com
                client-secret: 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
                redirect-uri: http://localhost:8080/login/oauth2/code/google
                scope:
                  - email
                  - profile
    
              facebook:
                client-id: 1244402233617077
                client-secret: 1df7576faa58e429bfdaaeefe68842c1
                scope:
                  - email
                  - public_profile

    위와 같이 google 이외에 facebook도 만들어줬다.

     

     

    다른 설정들은 구글때 이미 다 해놨기 때문에 로그인을 하면 정상적으로 진행될 것이다.

    페이스북으로 로그인 하여 자동 회원가입으로 db에 저장된 사진이다. providerId를 보면 NULL이 들어가 있다.

     

     

     

    저번 포스팅에서 PrincipalOauth2UserSservice를 보면 builder로 생성자를 만들기 위해서 사용자의 정보를 가져오는 부분 이 있었다.

     

    여기서 2번째 줄인 providerId는 해당 로그인의 PK 같은 개념이라고 했었다. 구글에서는 sub로 표현하지만 페이스북은 key 값이 id이기 때문에 NULL이 들어가는 것이다.

    구글에서는 sub였는데 여기서는 id이다.

     

    이러면 유지보수가 어렵기 때문에 하나로 통합시킬 수 있는 것이 필요하다.

     

     

     

    public interface OAuth2UserInfo {
        String getProviderId();
        String getProvider();
        String getEmail();
        String getName();
    }

    OAuth2UserInfo라는 인터페이스를 만들었다.

    provider는 구글, 페이스북인지가 들어가고, getProviderId는 각각 회원의 id가 들어간다.

     

     

     

     

    GoogleUserInfo.class

    public class GoogleUserInfo implements OAuth2UserInfo {
    
        private Map<String, Object> attributes; // getAttributes
    
        public GoogleUserInfo(Map<String, Object> attributes) {
            this.attributes = attributes;
        }
    
        @Override
        public String getProviderId() {
            return (String) attributes.get("sub"); // 페이스북이니까 sub
        }
    
        @Override
        public String getProvider() {
            return "google";
        }
    
        @Override
        public String getEmail() {
            return (String) attributes.get("email");
        }
    
        @Override
        public String getName() {
            return (String) attributes.get("name");
        }
    }

    구글의 정보를 담을 수 있도록 OAuth2UserInfo를 implements 한 구현체이다.

     

    attributes를 받아와서 getProviderId()부터 getName()까지 구현하면 된다. 페이스북은 getProviderId()의 파라미터에 id가 들어갈 것이며, getProvider()에서는 facebook을 return 할 것이다.

     

     

     

    PrincipalOauth2UserService.class

    @Service
    public class PrincipalOauth2UserService extends DefaultOAuth2UserService {
    
    ... (생략)
    
            OAuth2UserInfo oAuth2UserInfo = null;
            if(userRequest.getClientRegistration().getRegistrationId().equals("google")) {
                oAuth2UserInfo = new GoogleUserInfo(oAuth2User.getAttributes());
            } else if (userRequest.getClientRegistration().getRegistrationId().equals("facebook")) {
                oAuth2UserInfo = new FacebookUserInfo(oAuth2User.getAttributes());
            } else {
                System.out.println("구글과 페이스북 로그인만 지원합니다.");
            }
            
            String provider = oAuth2UserInfo.getProvider();
            String providerId = oAuth2UserInfo.getProviderId();
            String username = provider+"_"+providerId;
            String password = bCryptPasswordEncoder.encode("password"); // OAuth 로그인을 하면 password가 필요없긴 함
            String email = oAuth2UserInfo.getEmail();
            String role = "ROLE_USER";
            // 각각의 변수들도 oAuth2User가 아닌 oAuth2UserInfo로 바꿔준다.
            
    ... (생략)
    }

    PrincipalOauth2UserService에서 OAuth2UserInfo를 null로 초기화 한 다음에, 조건문을 활용해서 getRegistrationid에 맞는 걸로 attributes를 담아서 oAuth2UserInfo에 넣어주면 된다.

     

    구글, 페이스북 로그인을 해봤더니 각각의 provider, providerId가 잘 나온것을 확인했다.

     

    이렇게 하면 나중에 유지보수하기 굉장히 쉬워진다. 다음 포스팅에서 네이버 로그인도 해볼 것인데, NaverUserInfo만 만들어주면 된다.

     

Designed by Tistory.