支付宝小程序实现类似微信小程序的登录流程
微信小程序的登录流程介绍
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域名合法性检查,用手机扫码预览就可以看到效果。