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的技术客服小哥告诉我在构造分享参数的时候, 执行参数字 ...
随机推荐
- JDK bin指令
jmap: 一.调用命令示例: jmap -F-dump:format=b,file=rmsheap.bin 6086 就会在当前目录下生成rmsheap.bin的文件,6086是Pid.-F是在某些 ...
- Linux route命令
route 命令 route命令用于显示和操作IP路由表.要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两个网络的网关来实现.在Linux系统中,设置路由通常是 为了解决以 ...
- 【POJ】3616 Milking Time(dp)
Milking Time Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10898 Accepted: 4591 Des ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(1)-前言与目录(转)
开发工具:VS2015(2012以上)+SQL2008R2以上数据库 您可以有偿获取一份最新源码联系QQ:729994997 价格 666RMB 升级后界面效果如下: 日程管理 http://ww ...
- JS实战应用之做LOL领图标任务~
说一个技术造福人类的故事,事情是这样的,我是英雄联盟的忠实玩家,在浏览官网的时候看到这样一个活动(http://lol.qq.com/act/a20161020teemo/index.html),有个 ...
- [ Python ] Flask 基于 Web开发 大型程序的结构实例解析
作为一个编程入门新手,Flask是我接触到的第一个Web框架.想要深入学习,就从<FlaskWeb开发:基于Python的Web应用开发实战>这本书入手,本书由于是翻译过来的中文版,理解起 ...
- python操作csv
# -*- coding: utf-8 -*- #python 27 #xiaodeng #CSV文件的写入(按行写入) import csv #csv文件,是一种常用的文本格式,用以存储表格数据,很 ...
- linux中sed命令
sed sed意为流编辑器(Stream Editor),在Shell脚本和Makefile中作为过滤器使用非常普遍,也就是把前一个程序的输出引入sed的输入,经过一系列编辑命令转换为另一种格式输出. ...
- C# 判断字体是否存在以及安装
1. 字体安装 在实际开发项目中,需要在客户端安装字体,一种是通过代码将字体文件复制到系统FONT目录即可,另一种通过安装文件实现,至于其他方式还未知晓. 1.1 软安装 public cla ...
- 使用ssh client与bash scripts轻松管理多台主机
当我们需要控制一个局域网中的很多台服务器时,一个简单的全局操作可能会被放大地异常繁琐,这时我们就会需要新的工具来快速完成这种工作. 我们将使用ssh客户端提供的一些工具来快速完成这一开发工作,我们的开 ...