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的技术客服小哥告诉我在构造分享参数的时候, 执行参数字 ...
随机推荐
- java web 程序---在线时长
思路:toLocalString()这个方法 <body> <% long t=session.getLastAccessedTime(); long t2=session.getC ...
- "锁"
“锁”,指的是状态切换,状态未切换完成,加上锁,完成后才打开锁. 下面例子要完成一个点击按钮切换颜色的小示例,先看未加“锁”时候的效果 <!DOCTYPE html> <html l ...
- 【BZOJ】1260 [CQOI2007]涂色paint(区间dp)
题目 传送门:QWQ 分析 区间dp, 详见代码 代码 /************************************************************** Problem: ...
- Mysql--可用的 MySQL 产品和专业服务
一.MySQL Community Edition(社区版):MySQL Community Edition is the freely downloadable version of the wor ...
- 【转】C#调用java类、jar包方法
原文地址:http://blog.csdn.net/black0707/article/details/5769366 一.将已经编译后的java中Class文件进行打包:打包命令JAR 如:将某目录 ...
- Netty使用Google的ProtoBuf
protobuf是由Google开发的一套对数据结构进行序列化的方法,可用做通信协议,数据存储格式,等等.其特点是不限语言.不限平台.扩展性强 Netty也提供了对Protobuf的天然支持,我们今天 ...
- sysbench基准测试(2)——oltp.lua测试
前面知道sysbench基准测试的主要步骤为:prepare(准备数据集)→ run(运行测试)→ cleanup(清除数据集) 这一节介绍oltp.lua测试. oltp基准测试模拟了一个简单的事物 ...
- android 2.3.3 配置github的两步骤
第一步:配置GitHub的总账号(Version Control) 第二步:配置具体的仓库(仓库名称你从GitHub网上添加)
- NodeJs中require use get typescript及其他知识点集合
NodeJs的Express使用 nodejs事件的监听与事件的触发 TypeScript学习笔记 深入浅出Node.js Nodejs开发Office插件 类百度文库文档上传.转换和展示功能项目开源 ...
- 利用CopyOnWriteArrayList解决并发修改异常问题
一.需求 多个线程再获取同一个集合里面的数据同时,修改集合中的数据. 二.有问题的写法 package com.duchong.juc; import java.util.ArrayList; imp ...