移動端(android)
1.在友盟對各平臺封裝的基礎上再次封裝,直接一個回撥拿到第三方平臺token,openid,unionid,nickname等資訊.
這一個方法中包含了使用者點選授權拿token,根據token拿個人資訊兩個步驟.
庫地址參見:UmengUtil
//其他平臺如loginByWeixin(this, new AuthCallback<WeixinInfo>()
UmengUtil.loginBySina(this, new AuthCallback<SinaInfo>() {
@Override
public void onComplete(int var2, SinaInfo info) {
Log.e("dd",info.toString());
}
@Override
public void onError( int var2, Throwable var3) {
}
@Override
public void onCancel( int var2) {
}
});複製程式碼
2.然後,把必要的資訊傳送到服務端
服務端
拿到token,openid等關鍵資訊,呼叫各平臺的api進行資訊核對校驗,
如果通過,執行下一步:
根據第三方的openid/unionid去我們的資料庫查閱,
如果沒有賬戶,則生成新的賬戶.如果有賬戶,就不用生成.
最後,將賬戶個人資訊取出,返回給客戶端.
這樣,就完成了登入操作.
資訊校驗的api:
校驗的規則一般都是: 根據客戶端傳來的token去各平臺拿openid,然後與客戶端傳來的openid比對,如果一致,就代表客戶端資料沒問題,校驗無誤.
sina
OAuth2/get_token_info
查詢使用者access_token的授權相關資訊,包括授權時間,過期時間和scope許可權。
URL:api.weibo.com/oauth2/get_…
HTTP請求方式:POST
請求引數
access_token:使用者授權時生成的access_token。
返回資料
{ "uid": 1073880650, "appkey": 1352222456, "scope": null, "create_at": 1352267591, "expire_in": 157679471 }
微信
注: 在微信賬戶體系中,unionid才是一個微信賬戶的唯一標識(而openid是跟公眾號,服務號等發生關聯產生的),所以微信的校驗是通過token和openid來獲取unionid,然後與客戶端傳來的unionid進行比對校驗.
http請求方式: GET
api.weixin.qq.com/cgi-bin/use…
返回說明
正常情況下,微信會返回下述JSON資料包給公眾號:
{ "subscribe": 1,
"openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M",
"nickname": "Band",
"sex": 1,
"language": "zh_CN",
"city": "廣州",
"province": "廣東",
"country": "中國",
"headimgurl": "[http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0](http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0)",
"subscribe_time": 1382694957,
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL",
"remark": "",
"groupid": 0}複製程式碼
1 請求地址
PC網站:graph.qq.com/oauth2.0/me
WAP網站:graph.z.qq.com/moc2/me
2 請求方法:GET
3 請求引數:access_token
4 返回說明
PC網站接入時,獲取到使用者OpenID,返回包如下:
callback( {"client_id":"YOUR_APPID","openid":"YOUR_OPENID"} );
注意解析openid時要將外層括號去掉才能拿到json.
永久登入的實現
問題
看起來像掉線
第三方授權和獲取資訊時,友盟工具會將相關資訊在本地儲存一份,以實現下次不用再吊起授權介面讓使用者再次點選.
但是,第三方token都是有過期時間的.超過了這個時間,授權介面是會被吊起的,這給使用者看起來就好像莫名其妙掉線了,體驗非常不好,那麼,要怎麼實現移動端第三方登入的永久登入呢?
一個解決方式
將第三方登入轉變成賬號密碼登入:
在這臺手機上第一次用第三方登入時,當然是吊起授權介面.
當服務端判定登入成功時,返回第三方賬戶體系的使用者id(openid/unionid)或者內部賬戶體系的uid,和服務端生成的一個密碼(UUID等演算法ramdom出來,反正不用使用者記)
客戶端拿到這兩個資料,加密後儲存到本地,下次進入app時,直接用這兩個來登入.
更進一步
token
為了避免每次都傳輸使用者名稱密碼(即使加了密,在網路暴露太多也不好),可以在登入成功後,服務端生成一個token和規定其有效期(設定長一點,十幾天一個月之類的),並下發,
每次客戶端拿本地token,判斷有效期,在有效期內用token登入或者作為登入驗證,過期就用使用者名稱密碼登入.
短時頻繁登入,以及多臺裝置搶登的處理
session處理
驗證使用者名稱密碼或者token通過後,如果同一個user的原session還存在:
先判斷是否為同一個ip,如果不是,kill原session,建立新的session.
如果是原ip,就不必建立新的session.
多臺裝置搶登問題
兩臺手機相隔很短的事件先後登入同一個賬戶,如果移動端實現了對使用者完全透明的過期重登機制,那麼還是會出現看起來兩臺手機同時登入同一個賬戶,而對於服務端來說,就是不斷地在建立session,銷燬session.
怎麼處理呢?
服務端的響應多增加一個錯誤碼類別:
原先的:登入token過期一個code
增加的: 其他裝置登入的一個code
客戶端拿到第二個code時,可以不再做自動重新登入,而是像QQ一樣彈出notification通知使用者,讓使用者主動選擇.