ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring + Facebook Login 연동
    IT, 프로그래밍/Spring 2018. 7. 18. 22:15

    페이스북 로그인을 통해 유저의 정보를 제공 받는 Api를 사용한 예제 입니다.



    페이스북 정책 변경으로 리다이렉트 URL의 스킴이 반드시 https 를 사용하도록 되어 있으므로, 만약 아직 서버에 SSL 설정이 되어 있지 않는 분들은 먼저 설정을 하시고 진행 해 주시기 바랍니다. 여기서 볼 수 있어요!



    그리고 Access Token을 이용한 oAuth2 방식에 익숙하지 않거나, 아예 처음이신 분들은 생활 코딩에 가셔서 강의를 한 번 훑고 오시는걸 추천 드립니다. 바로가기



    1 Facebook for Developers로 이동해서 새 앱을 만듭니다. --> 이동 




    2. 로그인 클릭 후 설정으로 들어가서 리다이렉트 받을 URL을 넣습니다. 이 URL의 스킴은 반드시 https로 시작해야 합니다.





    3. 대시보드의 기본설정으로 가서 Client ID와 Secret Code를 확인합니다.





    4. pom.xml에 의존성을 추가합니다.



    1
    2
    3
    4
    5
    6
            <dependency>
                <groupId>org.springframework.social</groupId>
                <artifactId>spring-social-facebook</artifactId>
                <version>2.0.3.RELEASE</version>
            </dependency>
     
    cs


    5. root-context.xml에 빈을 추가 해 줍니다.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
        <!-- Facebook 소셜 로그인 연결 설정 -->
     
        <bean id="connectionFactory"
            class="org.springframework.social.facebook.connect.FacebookConnectionFactory">
            <constructor-arg value="Client ID" />
            <constructor-arg value="Secret Code" />
        </bean>
     
        <bean id="oAuth2Parameters"
            class="org.springframework.social.oauth2.OAuth2Parameters">
            <property name="scope" value="email" />
            <property name="redirectUri" value="https://localhost:8443/Path..." />
        </bean>
     
     
     
    cs


    scope는 유저의 정보를 가져올 범위를 말합니다. 여러 개의 정보를 , 로 연결하여 가지고 올 수 있습니다. (email, id, gender...)


    더 자세한 내용은 페이스북 디벨롭퍼 페이지를 이용하세요.


    6. Controller를 작성합니다.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    // 페이스북 oAuth 관련
        @Autowired
        private FacebookConnectionFactory connectionFactory;
        @Autowired
        private OAuth2Parameters oAuth2Parameters;
     
    // join  뷰로 매핑
        @RequestMapping(value = "/join", method = { RequestMethod.GET, RequestMethod.POST })
        public String join(HttpServletResponse response, Model model) {
            
            OAuth2Operations oauthOperations = connectionFactory.getOAuthOperations();
            String facebook_url = oauthOperations.buildAuthorizeUrl(GrantType.AUTHORIZATION_CODE, oAuth2Parameters);
        
            model.addAttribute("facebook_url", facebook_url);
            System.out.println("/facebook" + facebook_url);
     
            return "member/join";
        }
    cs


    root-context.xml에 정의한 빈을 @Autowired로 주입하고 요청할 url을 만들어 뷰로 보냅니다. (Client ID와 비밀 코드, 지정한 scope, redirect URL 등) 


    7. join.jsp로 이동하여 버튼에 생성한 url을 전달합니다. 


    1
    2
    3
    4
        <a href="${facebook_url}"><button
                                        class="btn btn-primary btn-round" style="width: 100%">
                                        <i class="fa fa-facebook" aria-hidden="true"></i>Facebook Login
                                    </button></a> 
    cs

    8. 콜백 받을 RequestMapping을 컨트롤러에 정의합니다.


    code도 함께 보내주니 String 타입의 응답 인자를 선언해 주면 됩니다.  사용자가 클릭 시 페이스북 사에 있는 관련 서버로 요청을 보내게 됩니다. 그리고 그 서버는 올바른 요청인지 판단하여 Access Token 발급 여부를 결정하여 Redirect URL으로 응답을 돌려주게 됩니다. AccessToken은 API를 사용할 수 있는 인증 토큰의 개념입니다. AccessToken의 유효성을 검사하여 만료되었으면 refresh Token을 꺼내옵니다.


    그리고 AccessToken으로 서버에 다시 요청하여 로그인 한 유저의 정보를 돌려 받습니다.


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
        @RequestMapping(value = "/facebookSignInCallback", method = { RequestMethod.GET, RequestMethod.POST })
        public String facebookSignInCallback(@RequestParam String code) throws Exception {
     
            try {
                 String redirectUri = oAuth2Parameters.getRedirectUri();
                System.out.println("Redirect URI : " + redirectUri);
                System.out.println("Code : " + code);
     
                OAuth2Operations oauthOperations = connectionFactory.getOAuthOperations();
                AccessGrant accessGrant = oauthOperations.exchangeForAccess(code, redirectUri, null);
                String accessToken = accessGrant.getAccessToken();
                System.out.println("AccessToken: " + accessToken);
                Long expireTime = accessGrant.getExpireTime();
            
                
                if (expireTime != null && expireTime < System.currentTimeMillis()) {
                    accessToken = accessGrant.getRefreshToken();
                    logger.info("accessToken is expired. refresh token = {}", accessToken);
                };
                
            
                Connection<Facebook> connection = connectionFactory.createConnection(accessGrant);
                Facebook facebook = connection == null ? new FacebookTemplate(accessToken) : connection.getApi();
                UserOperations userOperations = facebook.userOperations();
                
                try
     
                {            
                    String [] fields = { "id""email",  "name"};
                    User userProfile = facebook.fetchObject("me", User.class, fields);
                    System.out.println("유저이메일 : " + userProfile.getEmail());
                    System.out.println("유저 id : " + userProfile.getId());
                    System.out.println("유저 name : " + userProfile.getName());
                    
                } catch (MissingAuthorizationException e) {
                    e.printStackTrace();
                }
     
            
            } catch (Exception e) {
     
                e.printStackTrace();
     
            }
            return "redirect:/join";
     
        }
    cs



    Facebook Login Api는 차후 또 변동이 생길 수 있으니 주기적으로 디벨롭퍼 페이지로 가서 확인 해 보시는게 좋습니다! 혹시 질문 있으시면 남겨주세요!!


Designed by Tistory.