java网站如何集成facebook第三方登录
第一次接触Facebook第三方登录,可能有些地方做的并不全面,只是尝试着做了一个小demo,因为国内接入Facebook的项目并不多,并且多数都是Android或iOS的实现,所以资料也特别少,在此做个小总结。
第三方登录主要就是OAuth2.0协议,了解OAuth2.0是必要的!
开发流程:
1、了解OAuth2.0
2、到Facebook官网注册开发者账号,创建应用(开发者平台(https://developers.facebook.com),如果尚未注册账号的请注册账号并进行登录)
3、代码实现
下面逐步介绍
1、了解OAuth2.0(摘自百度百科)
①定义
【百度】OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAUTH是安全的。oAuth是Open
Authorization的简写。
【官网】
OAuth 2.0 is the industry-standard
protocol for authorization. OAuth 2.0 supersedes the work done on the
original OAuth protocol created in 2006. OAuth 2.0 focuses on client
developer simplicity while providing specific authorization
flows for web applications, desktop applications, mobile phones, and
living room devices. This specification is being developed within theIETF OAuth WG.
②认证授权过程
【图片】
图1:官网提供的认证流程
图2:百度上搜个好看的给同学们理解
如果以上没看太明白的话不要紧,跟着我后面一步一步走,会慢慢理解的
2、到Facebook官网注册开发者账号,创建应用
①要登录www.facebook.com毫无疑问需要FQ,这个如果不会的话问问身边的其他人总有人会的
②注册Facebook开发者账号这个就到官网一步一步来就好了,属于傻瓜式注册账号
③创建应用成功后会给你一个应用编号和应用秘钥,这两个要保留在代码中会用到
创建应用还需要填写一些网址什么的,我给同学们标识几个重要的地方:
<1>创建成功之后的页面,应用编号和秘钥一定要妥善保存到代码中
<2>在设置>基本中配置应用域名,访问应用时的域名,随便写一个配置到hosts文件中即可,不会的看下图:
<3>你的网站的入口访问地址
<4>如图这样配置就可以,那个跳转网址是用户登录成功之后回调的地址(不明白的接着往下走,有个印象就行,这个随时可以改)
基本上这些都配置好了就可以开始写代码了
3、代码实现(分为两类同学,分别找对应自己的实现方式)
【靠自己】想自主实现的同学,我截图具体位置,慢慢摸索同样可以做出来
想在后台做验证的同学看这里(这种方式比较安全,且可扩展性强,不需要调用facebookAPI)
想都在网页上实现的同学看这里
【无力者】不想自己找文档,不想思考,着急做的同学,看我上传的代码,复制粘贴就可以了
①我的index.jsp(对应我的应用的网址)
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>登录页面</title>
- </head>
- <script type="text/javascript" src="/static/jquery-1.7.2.min.js"></script>
- <body>
- <h1>Login Page</h1>
- <form action="${pageContext.request.contextPath }/login">
- username: <input type="text" name="username"><br /> <br />
- password: <input type="password" name="password"><br /> <br />
- <input type="submit" value="登录">
- </form>
- <br />
- <fb:login-button scope="public_profile,email"
- onlogin="checkLoginState();"
- auto_logout_link="true"
- size="large"
- show_faces="true">
- </fb:login-button>
- <div id="status"></div>
- <script>
- // This is called with the results from from FB.getLoginStatus().
- function statusChangeCallback(response) {
- console.log('statusChangeCallback');
- console.log(response);
- if (response.status === 'connected') {
- <span style="color:#FF0000;">//到此代表用户登录成功</span>
- <span style="color:#FF0000;">//跳转到http://gntina.iok.la/code(参见我后台代码的路径)</span>
- location.href = "<span style="color:#FF0000;">发送重定向的地址</span>";
- } else {
- document.getElementById('status').innerHTML = 'Please log '
- + 'into this app.';
- }
- }
- function checkLoginState() {
- FB.getLoginStatus(function(response) {
- statusChangeCallback(response);
- });
- }
- window.fbAsyncInit = function() {
- FB.init({
- appId : '<span style="color:#FF0000;">应用编号</span>',
- cookie : true, // enable cookies to allow the server to access
- xfbml : true, // parse social plugins on this page
- version : 'v2.8' // use graph api version 2.8
- });
- FB.getLoginStatus(function(response) {
- statusChangeCallback(response);
- });
- };
- // Load the SDK asynchronously
- (function(d, s, id) {
- var js, fjs = d.getElementsByTagName(s)[0];
- if (d.getElementById(id))
- return;
- js = d.createElement(s);
- js.id = id;
- js.src = "//connect.facebook.net/en_US/sdk.js";
- fjs.parentNode.insertBefore(js, fjs);
- }(document, 'script', 'facebook-jssdk'));
- </script>
- </body>
- </html>
②controller代码
- package com.lenovo.login.controller;
- import java.io.IOException;
- import java.util.HashMap;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import net.sf.json.JSONObject;
- import org.apache.commons.lang.StringUtils;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.ResponseBody;
- /**
- * @ClassName: TestController
- * @Description: FaceBook第三方登录
- * @date Mar 15, 2017
- */
- @Controller
- public class TestController {
- //应用编号
- private static String client_id="<span style="color:#FF0000;">应用编号</span>";
- //应用秘钥
- private static String client_secret="<span style="color:#FF0000;">应用秘钥</span>";
- //表示取得的用户信息的权限范围
- private static String scope = "user_about_me,email,read_stream";
- //回调地址
- private static String redirect_url ="http://gntina.iok.la/doLogin";
- //获取临时口令
- private static String code_url="https://www.facebook.com/v2.8/dialog/oauth";
- //获取访问口令
- private static String token_url="https://graph.facebook.com/v2.8/oauth/access_token";
- //获取用户信息
- private static String user_url="https://graph.facebook.com/me";
- //验证口令
- private static String verify_url="https://graph.facebook.com/debug_token";
- //获取应用口令
- private static String app_url="https://graph.facebook.com/v2.8/oauth/access_token";
- <span style="color:#FF0000;"> //第一步访问登录页面</span>
- @RequestMapping(value="/index")
- public String toIndex(HttpServletRequest request){
- return "index";
- }
- /**
- * @throws IOException
- * @Title: doLogin
- * @Description: 调用“登录”对话框和设置重定向网址
- * @return void <span style="color:#FF0000;">这个就是在应用中定义的跳转网址,也就是重定向第二步之后回调的地址,并且带上了code参数</span>
- * @date Mar 17, 2017 9:29:03 AM
- * @throws
- */
- @RequestMapping(value="/doLogin")
- @ResponseBody
- public Object doLogin(HttpServletRequest request,HttpServletResponse response) throws IOException{
- String code = request.getParameter("code");<span style="color:#FF0000;">//第二步获取code,迷糊的同学往下看,方法上也有对应的步骤</span>
- if(StringUtils.isNotBlank(code)){
- String accessToken = getFacebookAccessToken(code);<span style="color:#FF0000;">//第三步,用code(临时口令)换取accessToken</span>
- JSONObject userInfo=null;
- if(StringUtils.isNotBlank(accessToken)){
- userInfo = getUserInfo(accessToken);<span style="color:#FF0000;">//第四步,用accessToken获取用户信息</span>
- }else{
- System.out.println("accessToken is null");
- }
- System.out.println(userInfo);
- return userInfo;
- //对用户信息进行处理
- }else{
- return "/code";
- }
- }
- /**
- * @throws ServletException
- * @throws IOException
- * @Title: getAuthorizationCode
- * @Description: 获取 Authorization Code(临时口令)
- * @author <span style="color:#FF0000;">第二步,在index.jsp中用户登录成功后就是跳转到这里,重定向此地址会在回调地址中的参数带上code </span>
- * @return String
- * @date Mar 17, 2017 9:30:38 AM
- * @throws
- */
- @RequestMapping(value="/code")
- public static void getAuthorizationCode(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException{
- response.sendRedirect(code_url+"?client_id="+client_id+"&redirect_uri="+redirect_url);
- }
- /**
- * @return
- * @throws IOException
- * @Title: getFacebookAccessToken
- * @Description:用临时口令获取访问口令 access_token
- * @author <span style="color:#FF0000;">第三步用code换取accessToken(调用的接口和参数在代码里找就能看明白了) </span>
- * @return String
- * @param code“登录”对话框重定向接收的参数。
- * @date Mar 15, 2017 11:36:11 AM
- * @throws
- */
- public static String getFacebookAccessToken(String code){
- HashMap<String, String> params = new HashMap<String,String>();
- params.put("client_id", client_id);
- params.put("redirect_uri", redirect_url);
- params.put("client_secret", client_secret);
- params.put("code", code);
- String[] responseResult =null;
- String accessToken =null;
- try {
- responseResult = HttpClientUtil.getStringByPost(token_url, params, null);
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (null != responseResult && responseResult[0].equals("200")) {
- String result = responseResult[1];
- JSONObject jsonObject = JSONObject.fromObject(result);
- accessToken = jsonObject.getString("access_token");
- }
- return accessToken;
- //获取,然后返回access_token
- /*{
- "access_token": {access-token},
- "token_type": {type},
- "expires_in": {seconds-til-expiration}
- }*/
- }
- /**
- * @throws IOException
- * @return
- * @Title: getUserInfo
- * @Description:根据 token口令获取用户信息
- * @author <span style="color:#FF0000;">第四步用accessToken获取用户信息(调用的接口和参数在代码里找就能看明白了)</span>
- * @return Map<String,String>
- * @date Mar 15, 2017 6:04:31 PM
- * @throws
- */
- public static JSONObject getUserInfo(String accessToken){
- HashMap<String, String> params = new HashMap<String,String>();
- String fields="id,name,birthday,gender,hometown,email,devices";
- params.put("access_token", accessToken);
- params.put("fields", fields);
- String[] responseResult =null;
- JSONObject userInfo=null;
- try {
- responseResult = HttpClientUtil.getStringByGet(user_url, params);
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (null != responseResult && responseResult[0].equals("200")) {
- String result = responseResult[1];
- userInfo = JSONObject.fromObject(result);
- }
- return userInfo;
- }
- /**
- * @Title: verifyToken
- * @Description: 调用图谱API,验证口令 app_id 和 user_id 字段将帮助您的应用确认访问口令对用户和您的应用有效。
- * @author <span style="color:#FF0000;">第五步验证访问的用户是否来自你的应用,防刷功能,防止恶意注册 </span>
- * @return String
- * @date Mar 17, 2017 9:50:38 AM
- * @throws
- */
- @RequestMapping("/verify")
- @ResponseBody
- public Object verifyToken(String accessToken){
- HashMap<String, String> params = new HashMap<String,String>();
- //检验口令
- accessToken="EAATb6fZCbwXgBAFlUThSX7xWMcwfVhpT8A9szvYkWsTqhJDjcILOLkTPReDYHx6BfWl67MXA2ZApPyc7FEDJGJ1bIrM0u8zQI6nszrcnzULDRuUG2gBWIjuZAe6CPZCYXBHClpsL8zhZAK4gVZC4N27ZAkZBPDscRJW0bRS05LisJAZDZD";
- //应用口令
- String access_token=getAppToken();
- params.put("input_token", accessToken);
- params.put("access_token", access_token);
- String[] responseResult =null;
- String data = null ;
- try {
- responseResult = HttpClientUtil.getStringByGet(verify_url, params);
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (null != responseResult && responseResult[0].equals("200")) {
- String result = responseResult[1];
- JSONObject jsonObject = JSONObject.fromObject(result);
- data = jsonObject.getString("data");
- System.out.println(data);
- }
- // {
- // "data": {
- // "app_id": 138483919580948,
- // "application": "Social Cafe",
- // "expires_at": 1352419328,
- // "is_valid": true,
- // "issued_at": 1347235328,
- // "metadata": {
- // "sso": "iphone-safari"
- // },
- // "scopes": [
- // "email",
- // "publish_actions"
- // ],
- // "user_id": 1207059
- // }
- // }
- return data;
- }
- /**
- * @Title: getAppToken
- * @Description: 获取应用口令(用来验证口令是否来自我的应用)
- * @author gaona
- * @return String
- * @date Mar 20, 2017 3:16:26 PM
- * @throws
- */
- public String getAppToken(){
- HashMap<String, String> params = new HashMap<String,String>();
- params.put("client_id", client_id);
- params.put("client_secret", client_secret);
- params.put("grant_type", "client_credentials");
- String[] responseResult =null;
- String appToken=null;
- try {
- responseResult = HttpClientUtil.getStringByGet(app_url, params);
- } catch (Exception e) {
- e.printStackTrace();
- }
- if (null != responseResult && responseResult[0].equals("200")) {
- String result = responseResult[1];
- JSONObject jsonObject = JSONObject.fromObject(result);
- appToken = jsonObject.getString("access_token");
- System.out.println(appToken);
- }
- return appToken;
- }
- }
上面的代码只是个demo,具体的逻辑和实现方式还要代码风格,就要靠同学们弄懂原理和流程后自己来决定了!
希望此文可以帮助到需要的同学,有不明白的地方欢迎随时留言!
写博客实在是太累了,下面关于Google第三方登录的和这个是一样的,不同的只是调用接口的地址和参数略有不同,有不放心的同学,我会抓紧时间补上的。
补:这两天又看了一下,换成SDK的方式更简单,直接调用facebook写好的代码,可以实现自动验证,也是一个不错的选择!
facebook.jsp
- <span style="color:#000000;"><%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <!DOCTYPE html>
- <html>
- <head>
- <title>Facebook Login Page</title>
- <meta charset="UTF-8">
- </head>
- <script type="text/javascript" src="/static/jquery-1.7.2.min.js"></script>
- <script>
- //引入 facebook SDK
- (function(d, s, id) {
- var js, fjs = d.getElementsByTagName(s)[0];
- if (d.getElementById(id))
- return;
- js = d.createElement(s);
- js.id = id;
- js.src = "//connect.facebook.net/en_US/sdk.js";
- fjs.parentNode.insertBefore(js, fjs);
- }(document, 'script', 'facebook-jssdk'));
- </script>
- <body>
- <h1>Login Page</h1>
- <form action="${pageContext.request.contextPath }/login">
- username: <input type="text" name="username"><br /> <br />
- password: <input type="password" name="password"><br /> <br />
- <input type="submit" value="登录">
- </form><!-- 普通登录 -->
- <br />
- <fb:login-button scope="public_profile,email"
- onlogin="checkLoginState();"
- auto_logout_link="true"
- size="large"
- show_faces="true">
- </fb:login-button><!-- facebook 按钮 -->
- <div id="status"></div><!-- 登录状态显示 -->
- <script>
- function statusChangeCallback(response) {
- //可用于后台验证,但是前台调用SDK则会自动验证
- var accessToken=response.authResponse.accessToken;
- console.log(response.authResponse.accessToken);
- if (response.status === 'connected') {//sdk会自动保留accessToken,并且验证该请求是否来自我的应用
- FB.api('/me?fields=name,first_name,last_name,email', function(response) {
- //将用户信息传回服务端
- window.location.href="http://gntina.iok.la/userInfo?userInfo="+JSON.stringify(response);
- /* $.ajax({
- url:"http://gntina.iok.la/userInfo",
- data:{
- userInfo:JSON.stringify(response)
- },
- dataType:"json",
- async:false,
- success:function(data){
- window.location.href="";
- }
- }); */
- document.getElementById('status').innerHTML =
- 'Thanks for logging in, ' + response.name + '!';
- });
- } else {
- document.getElementById('status').innerHTML = 'Please log '
- + 'into this app.';
- }
- }
- function checkLoginState() {
- FB.getLoginStatus(function(response) {
- statusChangeCallback(response);
- });
- }
- window.fbAsyncInit = function() {
- FB.init({
- appId : '应用编号',
- cookie : true,
- xfbml : true,
- version : 'v2.8'
- });
- FB.getLoginStatus(function(response) {
- statusChangeCallback(response);
- });
- };
- </script>
- </body>
- </html></span>
controller
- @RequestMapping(value = "/userInfo")
- @ResponseBody
- public String getUserInfo(String userInfo) {
- System.out.println(userInfo);
- return userInfo;
- }
直接在页面上完成SDK的调用,把用户信息传回后台即可。
java网站如何集成facebook第三方登录的更多相关文章
- 网站如何集成Facebook和Twitter第三方登录
最近公司要求做海外的第三方登录:目前只做了Facebook和Twitter;国内百度到的信息太少VPN FQ百度+Google了很久终于弄好了.但是做第三方登录基本上都有个特点就是引入必须的js,设置 ...
- Django rest framework集成微博第三方登录
Django restframework 集成第三方登录(微博.微信.QQ等) 友情链接 python-social-auth-app官方文档 微博开放者平台 QQ开放者平台 准备工作 1.注册微博开 ...
- android开发学习——facebook第三方登录,看了你不会后悔
给APP用原生android进行facebook第三方登录. 我们做一件事情,首先得了解其原理,这样才不会迷茫,才知道自己做到什么程度了,心里才会有底. 所以,第一步,了解第三方登录的原理:下面贴一些 ...
- 用 Flask 来写个轻博客 (23) — 应用 OAuth 来实现 Facebook 第三方登录
目录 目录 前文列表 扩展阅读 第三方登录流程 OAuth 应用 OAuth 实现 Facebook 第三方登录 实现效果 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 Flask ...
- swift-sharesdk集成微信、Facebook第三方登录
好久没有写博客了.最近忙得没有时间更新博客,很忙很忙. 今天就把自己做过的第三方集成和大家分享一下,请大家多多指教. 第一步: 一.获取AppKey(去官方平台注册) 二.下载SDK 三.快速集成 第 ...
- 关于Google+以及Facebook第三方登录实现的一点总结
简述 最近项目中有关于第三方登陆的需求,第三方Facebook以及Google +登录. 正好这几天把这个需求做得差不多了,收个尾,作为一个这方面之前基本从未涉及的小白,总结下开发流程以及过程中遇到的 ...
- Android 集成支付宝第三方登录
前言: 在集成支付宝支付的时候遇到一点小麻烦,先在此记录供大家参考 1.授权 支付宝第三方登录需要在后台进行授权,在查看授权的时候我们一定要看清楚时候真的已经获得了权限(我在没有获取权限的情况下集成的 ...
- facebook第三方登录
一:创建和配置开发者应用 https://developers.facebook.com 登录开发者(可能要手机验证,身份证严重)->创建应用(web )->填写配置,网站网址和应用域名需 ...
- 使用ShareSDK完成Facebook第三方登录和Facebook分享时没办法跳转到Facebook应用
楼主是通过cocoapod接入ShareSDK, 后来发现无论是使用fb分享还是登录, 都是跳出了网页认证(即使我的手机有安装了fb) 后来mob的技术客服小哥告诉我在构造分享参数的时候, 执行参数字 ...
随机推荐
- appium历史版本下载地址
https://github.com/appium/appium-desktop/releases
- kafka 常用命令
Kafka 解压,进入kafka目录下的bin目录 启动zk nohup ./zookeeper-server-start.sh ../config/zookeeper.properties & ...
- 【洛谷】P2694 接金币(排序)
题目描述 在二维坐标系里,有N个金币,编号0至N-1.初始时,第i个金币的坐标是(Xi,Yi).所有的金币每秒向下垂直下降一个单位高度,例如有个金币当前坐标是(xf, yf),那么t秒后金币所在的位置 ...
- 【转】BMR(Block Media Recovery)
关于RMAN的块恢复.Block是oracle数据库最小恢复单位.鉴于此,BMR可以大大缩短恢复的时间,另外,在进行BMR时不需要停掉数据库,可以直接在数据库open状态对数据文件进行恢复,只是需要恢 ...
- 01——微信小程序官方demo讲解——文件结构
1.环境概览 首先环境配置的部分略过,打开小程序开发工具.选择一个空目录,即可开始一个demo项目. 其中新建成功后的目录如图所示: 2.文件结构描述 如图所示,左边是界面展示,右边是目录结构. 目录 ...
- MessageBox 函数
函数原型: int WINAPI MessageBox( _In_opt_ HWND hWnd, _In_opt_ LPCTSTR lpText, _In_opt_ LPCTSTR lpCaption ...
- Windows 10 提权漏洞复现及武器化利用
项目地址:https://github.com/SandboxEscaper/randomrepo 相关工具的下载地址: Process Explorer:https://docs.microsoft ...
- OD 实验(二) - 绕过序列号验证
需要破解的程序 输入用户名和序列号,点击 Check,程序会进行校验 用 OD 打开程序 按快捷键 Ctrl+F9 跟随表达式 GetDlgItemTextA 点击 ok 在这里调用了 GetDlgI ...
- ODPS基础
遇到一个项目需求是统计128张分库分表的数据表记录的最大id,通过单表查询计算非常费时,也无法应对分表数更多的情况,因此考虑到通过odps进行任务发布和运算 在云端 http://d2.alibaba ...
- Tkinter Label(标签)
Tkinter Label : 这个小工具,实现了显示框,在那里你可以把文本或图像.这个widget中显示的文本可以在任何时候你想要更新. 这个小工具,实现了显示框,在那里你可以把文本或图像. ...