IT·인터넷/CODE

spring java facebook 로그인 연동하기

ukidugi 2017. 9. 29.


scribejava-apis에서 제공한 예제




<dependency>
  <groupid>org.gnu</groupid>
  <artifactid>gnu-crypto</artifactid>
  <version>2.0.1</version>
</dependency>
		
<dependency>
  <groupid>org.springframework.social</groupid>
  <artifactid>spring-social-facebook</artifactid>
  <version>1.1.1.RELEASE</version>
</dependency>
 
<dependency>
  <groupid>org.apache.httpcomponents</groupid>
  <artifactid>httpclient</artifactid>
  <version>4.5.3</version>
</dependency>
		
<dependency>
  <groupid>com.github.scribejava</groupid>
  <artifactid>scribejava-apis</artifactid>
  <version>4.2.0</version>
</dependency>
		
<dependency>
   <groupid>com.github.scribejava</groupid>
   <artifactid>scribejava-core</artifactid>
  <version>4.2.0</version>
</dependency>



@Controller
@RequestMapping("/loginMember")
public class LoginMemberController {

	private static final Logger logger = LoggerFactory.getLogger(LoginMemberController.class);
	private static final String PROTECTED_RESOURCE_URL = "https://graph.facebook.com/v2.10/me?fields=id,email,name"; 
        //fields 에 안써주면 정보를 안가져옴

	/**
	 * 로그인 페이지
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/login.msc")
	public String login(HttpServletRequest request,HttpServletResponse response,Model model, HttpSession session) throws Exception {
		
		String denied = request.getParameter("denied");
		if (!StringUtil.isEmpty(denied)) {
			
			String msg = "";
			int cd_result = NumberUtil.stringToInt(denied);
			//로그인 에러 코드에 따라 메시지 출력
			switch (cd_result) {
				
			}
			model.addAttribute("msg", msg);
		}
		
		// facebook 로그인 url 가져오기
		final String clientId = Const.ID_FACEBOOK; //페이스 북 앱 아이디
    	        final String clientSecret = Const.SECRET_FACEBOOK; //페이스 북 공통코드
    	        final String secretState = "secret" + new Random().nextInt(999_999); //시크릿 난수코드 만듬
    	        final OAuth20Service service = new ServiceBuilder(clientId)
    			.apiSecret(clientSecret)
    			.state(secretState) 
    			.scope("email") //scope 란 facebook 회원정보 수락한 사람에 정보를 가져옴.. 
    			.callback(Const.URL_FACEBOOK_CALLBACK) //콜백 url 회원이 수락이 누를시 어디로 콜백 때릴건지 url 정의 해주면 된다
    			.build(FacebookApi.instance());
    	
    	session.setAttribute("secretState", secretState);

    	final String authorizationUrl = service.getAuthorizationUrl();
    	
    	model.addAttribute("oauthUrl",authorizationUrl);
       //facebook 보내준 authorizationUrl 모델에 추가 시켜준다.
    	
		return "/login/loginMember";
	}
	
	/**
	 * 페이지 접근권한 view 페이지 
	 * @param model
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/403.msc")
	public String accessDenied(Model model) throws Exception {
		return "/login/403";
	}
	
        //페이스북 로그인 정보 수락 시 콜백 url은 여기!
	@RequestMapping("/loginFacebook.msc")
	public String loginFacebook(Model model, @RequestParam(required = false) String state, @RequestParam(required = false) String code) throws Exception {
		
		logger.info("=== 시스템 [프론트], 페이스북 로그인 시작 ["  + DateUtil.getCurrentDateTime() + "] ===");
		String view = "login/loginMember";
		try {
			final String clientId = Const.ID_FACEBOOK;
			final String clientSecret = Const.SECRET_FACEBOOK;
			final OAuth20Service service = new ServiceBuilder(clientId)
					.apiSecret(clientSecret)
					.state(state) 
					.callback(Const.URL_FACEBOOK_CALLBACK)
					.build(FacebookApi.instance());
			
			// Trade the Request Token and Verfier for the Access Token 
			final OAuth2AccessToken accessToken = service.getAccessToken(code); 
			logger.info("Got the Access Token!"); 
			logger.info("(if your curious it looks like this: " + accessToken 
					+ ", 'rawResponse'='" + accessToken.getRawResponse() + "')"); 
			// Now let's go and ask for a protected resource! 
			logger.info("Now we're going to access a protected resource..."); 
			final OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL); 
			service.signRequest(accessToken, request); 
			final Response response = service.execute(request); 
			
			ObjectMapper objectMapper = new ObjectMapper();
			Map map = null;
			//오브젝트 매퍼해서 가져오면 된다.. 간혹 안가져오는 경우가 있음
			if (response.getCode() == 200) {
				map = objectMapper.readValue(response.getBody(), new TypeReference>(){});
				String facebookParam = map.get("id")+","+map.get("email")+","+map.get("name");
				logger.info("▶ 페이스북 리턴값=[" + facebookParam + "]");
				model.addAttribute("facebookParam",facebookParam);

				view = "login/facebookMember";
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			view = "login/facebookMember";
		}
		logger.info("=== 시스템 [프론트], 페이스북 로그인 종료 ["  + DateUtil.getCurrentDateTime() + "] ===");
		return view;
	}
}

로그인 페이지 jquery 써서 해당 페이스북 페이지로 연결 시켜 주도록 합니다.

모델에 담았기 때문에 jstl 써서 코드처럼 하시면 됩니다.

팝업 형식으로 하실려면 주석 풀고 location.href 주석 처리면 되겠습니다.!

//페이스북 로그인 버튼을 클릭시 oauthUrl 또는 access_token 체크 뒤 oauthurl 페이지 이동
function fnFacebook() {
	var windowW = 1100;  // 창의 가로 길이
	var windowH = 800;  // 창의 세로 길이
	var left = Math.ceil((window.screen.width - windowW)/2);
        var top = Math.ceil((window.screen.height - windowH)/2);
       
    
    //window.open('${oauthUrl}',"facebookLogin", "top="+top+", left="+left+", height="+windowH+", width="+windowW);
      location.href='${oauthUrl}';
    
}



콜백 함수 호출하면 jsp 입니다. 해당 값들이 안들어오면 정보 수락해달라는 문구

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/WEB-INF/include/taglibs.jsp"%>
<%@ include file="/WEB-INF/include/head.jsp"%>
<script type="text/javascript">
$(function(){
	var facebookParam = "${facebookParam}";
    var jbSplit = facebookParam.split( ',' );
    $("input[name=j_username]").val(jbSplit[1]);
    $("input[name=j_password]").val(jbSplit[0]);
    
    $("input[name=last_name]").val(jbSplit[2]);
    $("input[name=id]").val(jbSplit[1]);
    $("input[name=pw]").val(jbSplit[0]);
	
    if (jbSplit[1] == null || jbSplit[1] == "null" || jbSplit[1] == ""){
    	alert("Please allow Facebook information.");
    	location.href="/loginMember/login.msc";
		return;
    } else {
    	checkMemberId();
    }
})

//멤버 아이디 체크
function checkMemberId(){
	$.ajax({ 
		type: 'POST' 
		, url: '/member/checkEmailId.msc' 
		, data : $("#signupForm").serialize()
		, async : true
		//, dataType : 'text' 
		, success: function(data) {
			if(data > 0){
				alert("This ID is not available.(MEMBER)");
				location.href="/loginMember/login.msc";
				return;
			} else {
				checkYnUseSnsId();
				return;
			}
		} 
	});	
}

//SNS 아이디 체크
function checkSnsId(){
	$.ajax({ 
		type: 'POST' 
		, url: '/member/checkSnsId.msc' 
		, data : $("#signupForm").serialize()
		, async : true
		//, dataType : 'text' 
		, success: function(data) {
			if(data > 0){
				$("#loginForm").submit();
				return;
			} else {
				signForm();
				return;
			}
		} 
	});	
}

function checkYnUseSnsId(){
	$.ajax({ 
		type: 'POST' 
		, url: '/member/checkYnUseSnsId.msc' 
		, data : $("#signupForm").serialize()
		, async : true
		//, dataType : 'text' 
		, success: function(data) {
			if(data > 0){
				alert("This ID is not available.(SNS)");
				location.href="/loginMember/login.msc";
				return;
			} else {
				checkSnsId();
				return;
			}
		} 
	});	
}

function signForm(){
	$.ajax({ 
		type: 'POST' 
		, url: '/member/signUp.msc' 
		, data : $("#signupForm").serialize()
		//, dataType : 'text' 
		, success: function(data) {
			if(data == true){
				$("#loginForm").submit();
			}
		} 
	});	
}
</script>


마지막은 해당 페이스북에서 넘겨준 id 를 암호화 처리해서 패스워드를 만들었습니다.

이상 스프링으로 facebook로그인 연동을 마치도록 하겠습니다

댓글