第三方登录开发-Facebook
这次这个项目要分别可以使用新浪微博,qq互联以及Facebook和Twitter授权登录
facebook目前只支持oauth2技术,个人理解其工作流程是当用户想访问当前网站,却不想注册账号,此时当前网站有其它主流网站的第三方登录支持功能,即使用当前站的合作网站的账号密码去第三方合作网站验证用户的合法性,验证成功则允许登录当前站点,无需知道第三方的账号密码。
开发前需要先注册一个facebook的应用,这样可以得到类似密钥的两个值,client_id和client_secret,这两个值是访问facebook url的必要参数;
还要对应用进行一些必要的设置,首先要设置访问facebook和facebook回调的域名,并且配置下白名单,里面为ip值,多个逗号分隔,facebook会校验当前访问的域名解析后对应的ip是否在白名单里面;
接下来注意沙箱选项一定不要启用,否则会获取不到用户的信息,这样facebook应用基本设置完毕,该开始编写请求代码了。
上面了解了oauth2的工作流程,接下来一起看看其步骤和原理。
当用户点击第三方登录按钮时,会跳转出第三方网站(以下统称为服务端)的登录页面,输入用户名密码后客户端会向服务端申请一个临时令牌(即code值),申请成功后客户端还要申请授权(即token值),如果是第一次访问则会跳出授权页面,用户是否允许访问其一些基本信息,如name、email、用户的Id、图片等基本信息,如果验证及授权通过,则登录当前站点,并且下次会默认之前选择的授权不会弹出提示,除非清除本地cookie。
现在我们来编写代码,首先看下facebook oauth2的几个基本参数和访问url。
基本参数:
1、CLIENT_ID = 107717212399602 //为注册应用得到的值
2、redirectUrl = http://blog.csdn.net/webgeek //为facebook回调当前站点的url
3、SCOPE = "&scope=user_about_me,email,read_stream"; //表示取得的用户信息的权限范围
访问url:
1、REQUEST_CODE_URL //发送,得到Authorization Code
https://www.facebook.com/dialog/oauth?" + "client_id="+CLIENT_ID+"&redirect_uri="+redirectUrl+"&response_type=code"+SCOPE;
2、REQUEST_TOKEN_URL //请求token url
https://graph.facebook.com/oauth/access_token
3、REQUEST_USER_URL //使用得到的token獲取用戶信息
https://graph.facebook.com/me
在这并没有使用facebook的官方封装好的工具类,因为有了访问的url(由官方API提供),其实就是发送http请求和接受响应的过程,所以接下来只是编写http的过程。
代码1-controller中:
public void visitUrl(String code, @Param("origURL") String origURL){
try {
if (origURL != null && !"".equals(origURL)) {
this.origUrl = origURL;
}
//获得响应对象,可按照自己的方式获取
HttpServletResponse response = inv.getResponse();
if (code != null && !"".equals(code)) {
String token = NuomiOauthApi.getFacebookAccessToken(code);
if(token == null || "".equals(token)) {
response.getWriter().write("get code error...");
}else {
String[] tokens = token.split("&");
for (String t : tokens) {
if (t.indexOf("access_token") != -1) {
//此处有可能返回的值有多余的数据,可按照开发实际情况来决定是否处理 token = t.split("=")[1].trim();
}
}
//此处调用验证通过用户的基本信息 Map<String, String> map = getLoginUser(token);
if (map != null) {
//此处是判断是否本地已经有此用户,是否需要本地注册,可得到用户信息后自行开发 this.isLoginUserOldOrNew(inv, map, origUrl);
}else {
response.sendRedirect(INiuxConstants.DOMAIN_TW+origUrl);
}
}
}else {
////此处是第一次申请code值时
response.sendRedirect(requestCodeUrl);
}
} catch (Exception e) {
e.printStackTrace();
}
}
代码2-:
/**
* 使用Authentication Code方式獲取AcessToken
* @param authCode
* @return
* 如果出錯,返回null
*/
public static String getFacebookAccessToken(String authCode) {
try {
StringBuffer urlStr = new StringBuffer(REQUEST_TOKEN_URL);
urlStr.append('?');
StringBuffer temp = new StringBuffer();
temp.append("client_id=").append(CLIENT_ID).append('&')
.append("redirect_uri=").append(redirectUrl).append('&')
.append("client_secret=").append(CLIENT_SECRET).append('&')
.append("grant_type=authorization_code").append('&')
.append("code=" + authCode);
urlStr.append(temp.toString());
log.info("urlStr: "+urlStr);
String token = getFacebookTokenFromUrl(urlStr.toString(), null);
log.info("get token by authCode: "+token);
return token;
} catch (Exception ex) {
log.error("get AccessToken error:" + ex.getMessage(), ex);
return null;
}
}
代码3:
/**
* 通過api和token獲取當前登錄的用戶信息
* @param token
* @return
* map of id/name;如果出錯,返回null
*/
public static Map<String, String> getLoginUser(String token) {
try {
StringBuffer urlStr = new StringBuffer(REQUEST_USER_URL);
urlStr.append("?").append("access_token="+encodeUrl(token));
log.info("getLoginUser urlStr:"+urlStr.toString());
JSONObject json = getFacebookJsonFromUrl(urlStr.toString(), null);
log.info("getLoginUser json:"+json);
if (!json.containsKey("id")) {
if (json.containsKey("error_reason")) {
String errorReason = json.getString("error_reason");
String errorDescription = json.getString("error_description");
log.warn("save to facebook failed. errorReason:" + errorReason + ", errorDescription:"+ errorDescription);
}
} else {
Map<String, String> userInfo = new HashMap<String, String>();
userInfo.put("id", json.getString("id"));
userInfo.put("name", json.getString("name"));
userInfo.put("email", json.getString("email"));
userInfo.put("gender", json.getString("gender"));
return userInfo;
}
} catch (Exception e) {
// log it
log.error("get user info failed......", e);
e.printStackTrace();
}
return null;// error
}
代码4:
/**
* 從特定的url中獲取json
* @param urlStr
* @param params
* @return
* json object ,or null if failed
*/
private static JSONObject getFacebookJsonFromUrl(String urlStr, Map<String, String> params) {
HttpClient httpClient = new DefaultHttpClient();
//http請求好多都不支持post方式,但支持get
HttpGet httpGet = new HttpGet(urlStr);
JSONObject json = null;
try {
HttpResponse response = httpClient.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
String aStr = IOUtils.toString(is);
json = JSONObject.fromObject(aStr);
} catch (Exception e) {
log.error("http client execute error:" + e.getMessage(), e);
}
return json;
}
以上就是整个开发的流程,还有几点需要注意:
1、发送请求的url中有个参数为回调url(即代码中的redirectUrl),此参数在请求code和token的时候值必须一致,否则无法得到授权
2、发送的url字符串应该encode一下,浏览器会自动解析
3、发送用户信息请求的时候,一定要用Get方式发送http请求
第三方登录开发-Facebook的更多相关文章
- .Net Oauth2.0 第三方登录开发(Facebook ,LinkedIn )
需求:OAuth2实现第三方网站授权并获取其相关数据来实现登录等功能 暂时支持Facebook ,LinkedIn ,基本大同小异,只是返回时的数据不同,需根据具体返回类型进行相应处理 1.OAuth ...
- 使用ShareSDK完成Facebook第三方登录和Facebook分享时没办法跳转到Facebook应用
楼主是通过cocoapod接入ShareSDK, 后来发现无论是使用fb分享还是登录, 都是跳出了网页认证(即使我的手机有安装了fb) 后来mob的技术客服小哥告诉我在构造分享参数的时候, 执行参数字 ...
- android开发学习——facebook第三方登录,看了你不会后悔
给APP用原生android进行facebook第三方登录. 我们做一件事情,首先得了解其原理,这样才不会迷茫,才知道自己做到什么程度了,心里才会有底. 所以,第一步,了解第三方登录的原理:下面贴一些 ...
- 第三方登录 (faceBook )
1.iOS 第三方登录(Facebook,Twitter...)http://www.jianshu.com/p/f64d5ad2ef2a
- 关于Google+以及Facebook第三方登录实现的一点总结
简述 最近项目中有关于第三方登陆的需求,第三方Facebook以及Google +登录. 正好这几天把这个需求做得差不多了,收个尾,作为一个这方面之前基本从未涉及的小白,总结下开发流程以及过程中遇到的 ...
- java网站如何集成facebook第三方登录
第一次接触Facebook第三方登录,可能有些地方做的并不全面,只是尝试着做了一个小demo,因为国内接入Facebook的项目并不多,并且多数都是Android或iOS的实现,所以资料也特别少,在此 ...
- 分享前端Facebook及Twitter第三方登录
最近公司要求做海外的第三方登录:目前只做了Facebook和Twitter;国内百度到的信息太少VPN FQ百度+Google了很久终于弄好了.但是做第三方登录基本上都有个特点就是引入必须的js,设置 ...
- Spring Security构建Rest服务-0102-Spring Social开发第三方登录之qq登录
图一 基于SpringSocial实现qq登录,要走一个OAuth流程,拿到服务提供商qq返回的用户信息. 由上篇介绍的可知,用户信息被封装在了Connection里,所以最终要拿到Connectio ...
- Spring Security构建Rest服务-1000-使用SpringSocial开发第三方登录之大白话OAuth协议
OAuth协议简介 OAuth协议要解决的问题 OAuth协议中的各种角色 OAuth协议运行流程 OAuth协议,在网上也看了一些资料,意思就是给你颁发一个临时的通行证,你拿着这个通行证可以访 ...
随机推荐
- 【MySQL】DNS与MHA/ZABBIX构建的高可用MySQL
MySQL实例组与DNS和MHA/ZABBIX架构示意图: DNS搭建:http://www.cnblogs.com/jiangxu67/p/4801230.html MHA分析:http://www ...
- unity3d发布Android程序
unity3d是一个跨平台的游戏开发引擎,可以使用c#开发各种平台上的游戏,如windows,Mac,Android,windows phone,IOS,Flash等.下面说下如何将开发好的unity ...
- 浅谈JavaScript的事件响应
原文出处: Christian Heilmann 译文出处:Chajn Science 每当猴子们问我JavaScript和DOM里啥东西最牛逼时,我都会一巴掌打回去:卧槽还用问么当然是事件响应了 ...
- systemctl
旧指令 新指令 使某服务自动启动 chkconfig --level 3 httpd on systemctl enable httpd.service 使某服务不自动启动 chkconfig - ...
- s3c6410_中断
参考: 1)<USER'S MANUAL-S3C6410X>Chapter 10 GPIO, Chapter 12 VECTORED INTERRUPT CONTROLLER 2)< ...
- eclipse指定启动的jdk
原文:http://my.oschina.net/noday/blog/203987 到eclipse目录,打开eclipse.ini文件,在指定位置加入你的jdk相关文件(如下面示例配置中-vm配置 ...
- C#winform初试报表
步骤1.新建一个窗口,拖一个ReportViewer控件上去,设置该控件的Dock为Fill. 步骤2.添加一个报表文件,如:Report1.rdlc,设置其中的参数,这里设置的参数和下面的代码里面的 ...
- SQL SERVER连接字符串学习
在使用connection string时遇到一些问题 字符串如下"Data Source= ******;Initial Catalog=******;Persist Security I ...
- MongoDB 创建数据库
语法 MongoDB 创建数据库的语法格式如下: use DATABASE_NAME 如果数据库不存在,则创建数据库,否则切换到指定数据库. 实例 以下实例我们创建了数据库 runoob: > ...
- 编写高质量代码改善C#程序的157个建议
1.使用StringBuilder或者使用string.Format("{0}{1}{2}{3}", a, b, c, d)拼接字符串. 2.使用默认转型方法,比如使用类型内置的P ...