AtmosphereMao

小程序登录 - 时序图

image
流程与OAuth2.0的授权码模式相似。

OAuth2.0 基本处理流程

  1. 得到授权码code
  2. 获取access_token
  3. 通过access_token,获取OpenID
  4. 通过access_token及OpenID调用API,获取用户授权信息

微信小程序登录处理流程

  1. 程序调用 wx.login() 接口获取临时登录凭证(code)(无需用户授权)
  2. 小程序提交 code 到服务器
  3. 服务器通过 appid、appsecret 和 code 请求微信接口,换取用户的 session_key 和 openid
  4. 服务器根据 openid 查找到对应的用户,存入 session_key ,然后为该用户生成 access_token (JWT)返回给小程序
  5. 用户拥有了 access_token ,小程序就可以调用需要身份认证的接口了

关于 session_key

此处的 session_key 为存储在服务器中、用于获取用户信息等微信接口时所需的key。每次调用 wx.login() 之后,微信都会自动生成新的 session_key ,导致之前的 session_key 失效,所以在必要的时候 wx.login() ,而且还要及时保存 session_key 到服务器,以备后续使用。

代码调试 配置(基于Laravel)

EasyWeChat

回到 Laravel 项目中,我们需要调用微信的接口,加密解密微信接口数据,为了加快开发,使用 EasyWeChat 进行开发,EasyWeChat已经封装好了微信相关的接口。

可以直接使用 EasyWeChat Laravel 5 的拓展包: overtrue/laravel-wechat。
安装引入拓展包:

1
2
$ cd ~/Code/LaravelProject
$ composer require "overtrue/laravel-wechat:~4.0"

Laravel 配置

发布配置文件:

1
$ php artisan vendor:publish --provider="Overtrue\LaravelWeChat\ServiceProvider"

修改配置文件,将小程序部分的注释打开:

config/wechat.php

1
2
3
4
5
6
7
8
9
10
11
/*
* 小程序
*/
'mini_program' => [
'default' => [
'app_id' => env('WECHAT_MINI_PROGRAM_APPID', ''),
'secret' => env('WECHAT_MINI_PROGRAM_SECRET', ''),
'token' => env('WECHAT_MINI_PROGRAM_TOKEN', ''),
'aes_key' => env('WECHAT_MINI_PROGRAM_AES_KEY', ''),
],
],

登录 微信公众平台,获取小程序 AppIDAppSecret

编辑 .env 配置文件,增加参数AppIDAppSecret:

1
2
3
# 小程序
WECHAT_MINI_PROGRAM_APPID=wx756787de07****
WECHAT_MINI_PROGRAM_SECRET=bb28893cc9cdb3e0f*********

WePY 中 Promise 安装

后面代码使用了Promise对象。根据wepy项目中使用Promise

在1.4.1以下版本,wepy生成的项目默认都会加入promise polyfill。

在1.4.1以后的版本,需要用户手动加入。

在WePY项目中:

1
2
3
$ yarn add promise-polyfill
// 在windws环境下要加上--no-bin-links
> yarn add promise-polyfill --no-bin-links

增加 this.use(‘promisify’); 使 API promise 化:

src/app.wpy

1
2
3
4
constructor () {
super()
this.use('requestfix')
this.use('promisify')

小程序获取 Code

在小程序中调用 wepy.login() 接口,获取 Code

src/app.wpy

1
2
3
4
5
onLaunch() {
wepy.login().then(res => {
console.log('login: ', res)
})
}

由于我们使用了 WePY 框架,所有小程序的接口都需要使用 wepy 对象调用,例如 wx.login() 就需要使用 wepy.login()

进行编译,在微信开发者工具 - Console 则可以看到code信息。

服务器获取 OpenID

用 tinker 进行调试:

1
2
3
4
$ cd ~/Code/LaravelProject
$ php artisan tinker
>>> $miniProgram = \EasyWeChat::miniProgram();
>>> $miniProgram->auth->session('CODE'); // 此处CODE为WePY获取到的code

获取 UnionID

关于UnionID

在以上返回信息如拥有UnionID情况,则无须用户再次授权:

  • 如果开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号。开发者可以直接通过 wx.login 获取到该用户 UnionID,无须用户再次授权。
  • 如果开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用。开发者也可以直接通过 wx.login 获取到该用户 UnionID,无须用户再次授权。

对于UnionID的限制条件:

  1. 该小程序项目成立前,已有对应的网站,并且已拥有用户。
  2. 网站已有API,用户可通过账号或微信登录。

UnionID创建

UnionID的获取需服务号通过微信认证

微信公众平台 - 开发 - 接口权限 - 网页授权获取用户基本信息 中设置回调页面域名,在用户授权同意给公众号后,会将该用户的unionID传入该域名。(正式公众号回调地址需为域名)