web实现QQ第三方登录.docx
《web实现QQ第三方登录.docx》由会员分享,可在线阅读,更多相关《web实现QQ第三方登录.docx(12页珍藏版)》请在冰豆网上搜索。
![web实现QQ第三方登录.docx](https://file1.bdocx.com/fileroot1/2023-2/3/5fdccc5a-8118-4678-9d71-399fc4d3927b/5fdccc5a-8118-4678-9d71-399fc4d3927b1.gif)
web实现QQ第三方登录
开放平台-web实现QQ第三方登录
--------肖宏伟
应用场景
web应用通过QQ登录授权实现第三方登录。
操作步骤
1 注册成为QQ互联平台开发者,
2 准备一个可访问的域名,如
3 创建网页应用,配置必要信息,其中包括域名以及回调地址;
其中域名需要验证,需确保对域名主机有足够的控制权限
4 获取应用appID、appKey进行开发
登录流程
开发平台的登录授权采取oauth2.0机制,这也是目前几乎所有互联网开放平台所采取的方式。
需更多了解oauth2.0可参考阮老师的文章:
实现方式
client-side
流程:
前端页面通过Implict方式登录授权->回调获得accessToken->获取openid->同步用户信息并登录
为了保证数据安全,在获取用户信息并登录这一步必须由服务端实现。
这种方式的开发相对便捷,也是后面的实战案例将要采取的方式。
server-side
流程:
由server端页面跳转到登录授权页面(Authorizationcode方式)->回调获得code->置换accessToken->获取openid->同步用户信息并登录
可参考:
SDK使用
JSSDK 可快捷实现前端登录授权的功能,可自定制登录按钮
使用文档:
缺点:
存在浏览器兼容风险,此外登录按钮UI的定制也存在受限
JavaSDK 屏蔽了oauth授权的复杂度,方便后端实现授权及api操作
缺点:
增加依赖jar包,项目容易变得臃肿,尤其是当前项目已经存在oauth功能实现时可不必采用。
案例实战
功能描述
clientside+server-side通过QQ网页授权登录,并获取用户信息
1 本地开发环境准备
修改hosts文件将映射到127.0.0.1;
本地服务器以80端口启动, windows下可能会出现80端口被系统进程占用的情况,解决方法可参考
本地服务器启动后,以的域名进行访问,在QQ登录授权时可通过域名验证这一步
2 登录跳转页面
QQ登录跳转
//切割字符串转换参数表
functiontoParamMap(str){
varmap={};
varsegs=str.split("&");
for(variinsegs){
varseg=segs[i];
varidx=seg.indexOf('=');
if(idx<0){
continue;
}
varname=seg.substring(0,idx);
varvalue=seg.substring(idx+1);
map[name]=value;
}
returnmap;
}
//隐式获取url响应内容(JSONP)
functionopenImplict(url){
varscript=document.createElement('script');
script.src=url;
document.body.appendChild(script);
}
//获得openid的回调
functioncallback(obj)
{
varopenid=obj.openid;
$("#openid").text(openid);
//跳转服务端登录url
varresulturl="@{openapi.QQs.login_result()}";
varaccessToken=$("#accessToken").text();
//向服务端传输access_token及openid参数
document.location.href=resulturl+"?
access_token="+accessToken+"&openid="+openid;
}
AccessToken:
--ExpireIn
OpenID:
--执行脚本-->
//应用的APPID
varappID="101207268";
//登录授权后的回调地址,设置为当前url
varredirectURI="@@{openapi.QQs.login()}";
//初始构造请求
if(window.location.hash.length==0)
{
varpath='
varqueryParams=['client_id='+appID,
'redirect_uri='+redirectURI,
'scope='+'get_user_info,list_album,upload_pic,add_feeds,do_like','response_type=token'];
varquery=queryParams.join('&');
varurl=path+query;
window.location.href=url;
}
//在成功授权后回调时location.hash将带有access_token信息,开始获取openid
else
{
//获取accesstoken
varaccessToken=window.location.hash.substring
(1);
varmap=toParamMap(accessToken);
//记录accessToken
$("#accessToken").text(map.access_token);
$("#expire").text(map.expires_in);
//使用AccessToken来获取用户的OpenID
varpath="
varqueryParams=['access_token='+map.access_token,'callback=callback'];
varquery=queryParams.join('&');
varurl=path+query;
openImplict(url);
}
功能描述
页面在第一次打开时跳转到QQ登录授权页面;
授权成功之后回到当前页面通过url参数(hash串)获得accessToken;
此后可通过jsonp方式获取用户的openid,url如:
获取到用户OpenID,返回包如下(JSONP方式获取):
callback({"client_id":
"YOUR_APPID","openid":
"YOUR_OPENID"})
将access_token及openid传到服务端进行处理
3 server端获取用户信息
接收openid的页面方法
/**
*登录结果
*
*@paramaccess_token
*@paramopenid
*/
publicstaticvoidlogin_result(Stringaccess_token,Stringopenid){
//调用api获取qq用户信息
QQUserInfouser=QQApi.getUserInfo(access_token,openid);
//此时若取得user信息,则可以进行保存,并执行用户登录操作
....
//登录成功后跳转
redirect(xxx);
}
QQApi的实现
/**
*QQ互联API
*
*
*登录流程:
*
*1前端跳转qq授权页面
*2js获得access_token
*3通过jsonp方式获得openid
*4server端根据上传的access_token及openid获取用户信息,如昵称、头像
*
*参考文档:
*
*
*
*@authorxxx
*@createDate2015年3月10日
*
*/
publicclassQQApi{
publicstaticStringappId="xxx";
publicstaticStringappSecret="xxx";
publicstaticStringbaseUrl="";
protectedstaticfinalStringURL_GET_USERINFO=baseUrl
+"/user/get_user_info?
access_token=%s&oauth_consumer_key=%s&openid=%s";
protectedstaticfinallongACCESS_TIMEOUT=15;
protectedstaticfinalStringDEF_APP_TOKEN_EXPIRE="3h";
/**
*获取用户信息
*
*
*
*
*
*调用地址:
*
*参数
*access_token=*************&
*oauth_consumer_key=12345&
*openid
*
*返回结果如下:
*{
*"ret":
0,
*"msg":
"",
*"is_lost":
0,
*"nickname":
"小吞",
*"gender":
"女",
*"province":
"广东",
*"city":
"广州",
*"year":
"1993",
*"figureurl":
"
*"figureurl_1":
"
*"figureurl_2":
"
*"figureurl_qq_1":
"
*"figureurl_qq_2":
"
*"is_yellow_vip":
"0",
*"vip":
"0",
*"yellow_vip_level":
"0",
*"level":
"0",
*"is_yellow_year_vip":
"0"
*}
*
*
*@paramaccessToken
*@return
*/
publicstaticQQUserInfogetUserInfo(StringaccessToken,Stringopenid){
if(StringUtils.isEmpty(accessToken)||StringUtils.isEmpty(openid)){
returnnull;
}
Stringurl=String.format(URL_GET_USERINFO,accessToken,appId,openid);
StringresultString=DefaultHttp.get(url,ACCESS_TIMEOUT,GlobalConstants.UTF_8);
Logger.debug("[sso-qq]get userinfo.useurl'%s'",url);
QQUserInfouserinfo=JsonUtil.fromJson(resultString,QQUserInfo.class);
if(userinfo==null||!
userinfo.hasGot()){
Logger.debug("[sso-qq]getuserinfofailed,withresultof'%s'",resultString);
returnnull;
}
Logger.debug("[sso-qq]getuserinfosuccess,withresultof'%s'",resultString);
returnuserinfo;
}