同事搞了个qq第三方登录,学习下.
qq第三方登录(qq oAuth2.0),在oauth的协议的基础上实现的(新浪,wx等一些第三方登录都遵循这个原则),第三方分网站与移动应用
网站接入:总体流程
QQ登录OAuth2.0总体处理流程如下:
Step1:申请接入,获取appid和apikey;
Step2:开发应用,并设置协作者帐号进行测试联调;
Step3:放置QQ登录按钮;
Step4:通过用户登录验证和授权,获取Access Token;
Step5:通过Access Token获取用户的OpenID;
Step6:调用OpenAPI,来请求访问或修改用户授权的资源。
1.申请接入
主要申请appid与appkey
appid-应用的唯一标识。在OAuth2.0认证过程中,appid的值即为oauth_consumer_key的值。
appkey:appid对应的密钥,访问用户资源时用来验证应用的合法性。在OAuth2.0认证过程中,appkey的值即为oauth_consumer_secret的值。
申请有2个重要的参数,域名-在什么网站显示第三方登录图标,回调地址-登录回调url(在此url中处理相关业务逻辑,比如绑定相关账号等等,此处命名为xx.callback.do)
2.java后台处理
下载java sdk中有个qqconnectconfig.properties更改里面的app_id,app_key,redirect_url(回调地址,与申请的写的保持一致),放在项目资源目录下
a.获取authorize code
前端点击登录回调url处理
String url = new Oauth().getAuthorizeURL(request);
//https://graph.qq.com/oauth2.0/authorize?client_id=***&redirect_uri=**.callback.do&response_type=code&state=***&scope=get_user_info
response.sendRedirect(url);
其中scope指的需要授权的相关内容,此处只需要用户相关信息,在qqconnectconfig.properties中配置
重定向一个url()后最终定向到认证页面https://graph.qq.com/oauth/show?which=Login&display=pc&client_id=****&redirect_uri=**xx.callback.do&response_type=code&state=**&scope=get_user_info
认证完成调戏回调地址
https://***/callBack.do?code=**&state=0548cd8ac801ff79d3fb8634237bdbcd
其中code就是获取的authorize code
b.利用authorize code 获取token,通过token 获取openId,通过token openId获取相关信息(sdk自己封装了调用)
try {
AccessToken accessTokenObj = (new Oauth()).getAccessTokenByRequest(request);
String accessToken = null,
openID = null;
long tokenExpireIn = 0L;
if (accessTokenObj.getAccessToken().equals("")) {
// 我们的网站被CSRF攻击了或者用户取消了授权
// 做一些数据统计工作
System.out.print("没有获取到响应参数");
} else {
accessToken = accessTokenObj.getAccessToken();
tokenExpireIn = accessTokenObj.getExpireIn();
request.getSession().setAttribute("demo_access_token", accessToken);
request.getSession().setAttribute("demo_token_expirein", String.valueOf(tokenExpireIn));
// 利用获取到的accessToken 去获取当前用的openid -------- start
OpenID openIDObj = new OpenID(accessToken);
openID = openIDObj.getUserOpenID();
UserInfo qzoneUserInfo = new UserInfo(accessToken, openID);
UserInfoBean userInfoBean = qzoneUserInfo.getUserInfo();
...................
//业务逻辑处理,利用accessToken,openId获取用户的qq的相关信息,并通过openId(一个qq用户对应一个openId)同自己业务进行绑定
................
认证完成跳转自己相关业务主页
response.sendRedirect("")
}
看了这个qq第三方,又瞄到了旁边的微信扫码登录,又瞄了下,微信跟qq第三登录大致很相似,此次页面的微信登录采用的是js实现网站内嵌二维码
1.申请app_id secret
2.前端内嵌js
引入js文件
定义js对象 (只需定义就好,会根据id标识进行点击触发)
var obj = new WxLogin({
//id标识
id:"wechat-img",
//appid
appid: "**",
//作用域 网站应用snsapi_login即可
scope: "snsapi_login",
//h
redirect_uri: "****callBack.do",
//用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
state: "****",
//样式 有black与white可选
style: "",
//自定义样式链接,第三方可根据实际需求覆盖默认样式
href: ""
});
定义链接与二维码div
//超链接
//显示二维码的div
点击超链接会在div 出出现一个二维码,当你不扫描时,每隔一段时间发送一个请求(主要是保证请求不被断掉,扫描会自动触发)
https://long.open.weixin.qq.com/connect/l/qrconnect?uuid=xxx&_=xxxx
其中一个二维码对应一个uuid,_=后面的就是上面的state
扫描之后是二维码上会提示已扫描,微信确认登录以后,调用回调接口
https://******callBack.do?code=***&state=***
其中的code就是authorize_code,state是js自己生成第一个状态码
3.后台代码
前端调用回调接口传递code,通过code获取token,通过token获取openId
微信没有相应的java jdk,只能手动调用(参考后台操作token微信官方文档)
通过code获取access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
参数说明
参数 是否必须 说明
appid 是 应用唯一标识,在微信开放平台提交应用审核通过后获得
secret 是 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
code 是 填写第一步获取的code参数
grant_type 是 填authorization_code
返回说明
正确的返回:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
参数 说明
access_token 接口调用凭证
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 授权用户唯一标识
scope 用户授权的作用域,使用逗号(,)分隔
错误返回样例:
{"errcode":40029,"errmsg":"invalid code"}
刷新access_token有效期
access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:
1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。
refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。
请求方法
获取第一步的code后,请求以下链接进行refresh_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
参数说明
参数 是否必须 说明
appid 是 应用唯一标识
grant_type 是 填refresh_token
refresh_token 是 填写通过access_token获取到的refresh_token参数
返回说明
正确的返回:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE"
}
参数 说明
access_token 接口调用凭证
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 授权用户唯一标识
scope 用户授权的作用域,使用逗号(,)分隔
错误返回样例:
{"errcode":40030,"errmsg":"invalid refresh_token"}
第三步:通过access_token调用接口
获取access_token后,进行接口调用,有以下前提:
1. access_token有效且未超时;
2. 微信用户已授权给第三方应用帐号相应接口作用域(scope)。
对于接口作用域(scope),能调用的接口有以下:
授权作用域(scope) 接口 接口说明
snsapi_base /sns/oauth2/access_token 通过code换取access_token、refresh_token和已授权scope
/sns/oauth2/refresh_token 刷新或续期access_token使用
/sns/auth 检查access_token有效性
snsapi_userinfo /sns/userinfo 获取用户个人信息
其中snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,从而导致无法获取到需要用户授权才允许获得的数据和基础功能。