同事搞了個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文件
<script src="https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
定義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
//超鏈接
<a id = "wechat-login" class="wechat-login"style="cursor:pointer;display: inline-block;margin:0 10px">
<img src="/img/icons/we0.png" class="weicon"
onMouseOver="this.src='/img/icons/we1.png'"
onMouseOut="this.src='/img/icons/we0.png'">
</a>
//顯示二維碼的div
<div id="wexin-login-form" class="form form-login" style="display: none;">
<div class="form-group">
<div id="wechat-img">
</div>
</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,從而導致無法獲取到需要用戶授權才允許獲得的數據和基礎功能。