支付宝小程序实现类似微信小程序的登录流程

微信小程序的登录流程介绍

https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html

关键点

  1. 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。
  2. 临时登录凭证 code 只能使用一次

TODO

查找支付宝小程序如何实现这几点?

  1. 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
  2. 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 和 会话密钥 session_key。

workflow

task

0. 支付宝小程序如何得到 临时登录凭证code

  1. 支付宝登录校验接口
  2. 自定义登陆态的方式

查看支付宝官方会员能力接口文档

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域名合法性检查,用手机扫码预览就可以看到效果。

扩展阅读

PHP中如何传递Session ID