微信小程序的登錄流程介紹
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
關鍵點
- 會話密鑰 session_key 是對用戶數據進行 加密簽名 的密鑰。為了應用自身的數據安全,開發者服務器不應該把會話密鑰下發到小程序,也不應該對外提供這個密鑰。
- 臨時登錄憑證 code 只能使用一次
TODO
查找支付寶小程序如何實現這幾點?
- 調用 wx.login() 獲取 臨時登錄憑證code ,並回傳到開發者服務器。
- 調用 auth.code2Session 接口,換取 用戶唯一標識 OpenID 和 會話密鑰 session_key。
workflow
task
0. 支付寶小程序如何得到 臨時登錄憑證code
- 支付寶登錄校驗接口
- 自定義登陸態的方式
查看支付寶官方會員能力接口文檔
https://opendocs.alipay.com/mini/00arkn
從上面文檔找到 用戶授權API : my.getAuthCode 接口得到 authCode
https://opendocs.alipay.com/mini/api/openapi-authorize
my.getAuthCode({
scopes: 'auth_base',//靜默授權。用戶基礎授權,僅用於靜默獲取用戶支付寶uid。靜默授權不彈框,直接獲取用戶信息。
success: (res) => {
my.alert({
content: res.authCode,
});
},
});
這樣就得到了 臨時登錄憑證code
注意:
用戶的 user_id 可以通過用戶授權 API 獲取嗎?
不可以,user_id 需要在服務器端調用 alipay.system.oauth.token 獲取。
所以,接下來看 alipay.system.oauth.token https://docs.open.alipay.com/api_9/alipay.system.oauth.token
官方php請求示例:
$aop = new AopClient ();
$aop->gatewayUrl = 'https://openapi.alipay.com/gateway.do';
$aop->appId = 'your app_id';
$aop->rsaPrivateKey = '請填寫開發者私鑰去頭去尾去回車,一行字符串';
$aop->alipayrsaPublicKey='請填寫支付寶公鑰,一行字符串';
$aop->apiVersion = '1.0';
$aop->signType = 'RSA2';
$aop->postCharset='GBK';
$aop->format='json';
$request = new AlipaySystemOauthTokenRequest ();
$request->setGrantType("authorization_code");
$request->setCode("4b203fe6c11548bcabd8da5bb087a83b");
$request->setRefreshToken("201208134b203fe6c11548bcabd8da5bb087a83b");
$result = $aop->execute ( $request);
$responseNode = str_replace(".", "_", $request->getApiMethodName()) . "_response";
$resultCode = $result->$responseNode->code;
if(!empty($resultCode)&&$resultCode != 10000){
echo "失敗";
} else {
echo "成功";
}
這樣就可以實現對 code 的校驗並獲取 支付寶uid(對比微信的openid)。
接下來,查找保存登錄態的方案,
搜索關鍵詞 保存登陸態方案
找到的有用結果:
https://www.jianshu.com/p/96d6e856b885 :小程序不支持 cookie ,所以這該方案需要測試
搜索關鍵詞 小程序保存登錄態的方案
對登陸態的解釋:
所謂的登錄態其實就是客戶端發送請求的時候攜帶的token(通常叫做令牌),當用戶輸入賬號密碼,驗證成功之后,服務端生成一個token傳遞給客戶端,客戶端在后續的請求中攜帶這個token,服務器進行校驗,校驗成功則處理客戶端的請求,校驗失敗則要求客戶端重新去登陸。
微信小程序跟傳統的web項目的不同之處在於它不依托於瀏覽器,所以它沒有cookie,自然無法用session來管理登錄態。
還有一個要注意的是,小程序也有自己的登錄態,那就是session_key的生命周期,session_key是小程序中為了加密數據而提供的一個密鑰,具有一定的生命周期。查看小程序官方文檔,可以知道它是在服務端調用code2Session獲取的。可以通過小程序的wx.checkSession()來校驗小程序端的登錄態是否過期。
微信小程序登錄態的方案
經過上面的分析,整理出小程序登錄態的方案。
1.在需要用戶登錄態的頁面,首先從緩存中獲取用戶數據userInfo,若無數據,則跳4
2.調用wx.checkSession()檢查小程序端的登錄態是否過期,若沒過期,跳3,若過期,跳4
3.調用服務端的代碼檢查session是否過期(即檢查服務端的登錄態),若沒過期則拿到用戶數據繼續執行后續的操作。若過期,則跳4.
4.登錄操作,登錄操作分為如下幾個步驟。
- a.小程序端調用wx.login 接口得到code。(code只能使用一次)
- b.服務端利用這個code訪問code2Session接口得到session_key和open_id,並將session_key和open_id存入到session中。
- c.服務端執行登錄操作,主要是通過open_id去數據庫中尋找用戶數據,若無則新增用戶到數據庫,若有則取出用戶數據。
- d.將用戶數據userInfo,session_key, open_id等數據都存放到session中,方便服務端下次拿。
- e.將用戶數據userInfo,連同session的sessionId一起響應給小程序端。
- f.小程序端得到用戶數據和userInfo后更新緩存中的userInfo(包括JESSIONID的值sessionId)
支付寶小程序登錄態方案
1.在需要用戶登錄態的頁面,首先從緩存中獲取用戶數據userInfo,若無數據,則跳4
2.調用wx.checkSession()檢查小程序端的登錄態是否過期,若沒過期,跳3,若過期,跳4
3.調用服務端的代碼檢查session是否過期(即檢查服務端的登錄態),若沒過期則拿到用戶數據繼續執行后續的操作。若過期,則跳4.
4.登錄操作,登錄操作分為如下幾個步驟。
- a.小程序端調用 my.getAuthCode 接口得到code。(code只能使用一次)
- b.開發者服務端用這個code訪問 支付寶接口服務器端 alipay.system.oauth.token 接口,請求過程其實也是一個校驗過程。得到 session_key 和 alipay_uid,並將session_key和alipay_uid存入到session中。
- c.開發者服務端執行登錄操作,主要是通過alipay_uid去數據庫中尋找用戶數據,若無則新增用戶到數據庫,若有則取出用戶數據。
- d.將用戶數據userInfo,session_key, alipay_uid等數據都存放到session中,方便服務端下次拿。
- e.將用戶數據userInfo,連同session的sessionId一起響應給小程序端。
- f.小程序端得到用戶數據和userInfo后更新緩存中的userInfo(包括JESSIONID的值sessionId)
支付寶小程序調試技巧
訪問的域名受限制:小程序IDE中,詳情處(右上角)忽略webview域名合法性檢查,用手機掃碼預覽就可以看到效果。