Laravel Passport & 微信小程序的登录态维护

更新日期: 2018-01-26 阅读次数: 17915 分类: 微信小程序

官方流程图

https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxchecksessionobject

目的

  • 拿到用户的 open_id
  • 维护用户与自己服务器的登录态

测试环境

Laravel 5.5

按照顺序描述

wx.login

在微信小程序客户端,直接与微信服务器交互,是拿不到用户 open_id 的。

需要

  1. 先用 wx.login (小程序直接调用微信服务器) 获取到用户凭证 code
  2. 小程序将 code 传给自己的服务器,在自有服务器上通过 api 将 code 换为 open_id, session_key

自有登录态的维护

Laravel 的 API 如何支持登录态的维护

Password Grant Tokens

The OAuth2 password grant allows your other first-party clients, such as a mobile application, to obtain an access token using an e-mail address / username and password. This allows you to issue access tokens securely to your first-party clients without requiring your users to go through the entire OAuth2 authorization code redirect flow.

php artisan passport:client --password

新建之后,会在 MySQL 数据表 oauth_clients 里看到,多了一条 password_client 为 1 的记录。 这条记录就不需要特别指定 redirect path。

通常,例如手机端需要帐号密码登录,来获取 access_token, 请求发送至 /oauth/token。

但是,像微信小程序,如果自动返回 access_token?

https://github.com/laravel/passport/issues/71

Password Grant Tokens 与 Personal Access Tokens 的区别是什么

从解释来看,Personal Access Tokens 更适合小程序的场景,即在通过微信 API 获取到用户 open id 之后,创建用户,然后自动生成 access token

// Creating a token with scopes...
$token = $user->createToken('My Token', ['place-orders'])->accessToken;

但是,由于 Personal Access Tokens 是永不过期的。(因为,Personal Access Tokens 主要用于给三方开发者体验,测试 oauth2 api。)

感觉,有一定的安全隐患

  • 被劫持,反复利用
  • 数据表无限增长?每次 login 都会生成一个新的 access_token?

生成 personal access client 的命令

php artisan passport:client --personal

如果运行过 passport:install 则不需要执行上面的命令。

路由保护

Route::get('/user', function () {
    //
})->middleware('auth:api');

客户端 js 请求如何附带上 access_token? 修改 headers

'headers' => [
        'Accept' => 'application/json',
        'Authorization' => 'Bearer '.$accessToken,
    ],

如何通过 access_token 获取对应的用户

request()->user()

wx.checkSession

用户越久未使用小程序,用户登录态越有可能失效。反之如果用户一直在使用小程序,则用户登录态一直保持有效。

检查用户登录态是否已经失效,失效之后,需要调用 wx.login

// checkSession 的时机 我觉得应该在 APP 的全局 onShow 里检测,理由是

要保证用户提交操作时,涉及到的微信api不会因过期而失效,在 onShow 时检测就可以。

session_key 有什么用

session_key 是对用户数据进行加密签名的密钥。为了自身应用安全,session_key 不应该在网络上传输。

// TODO session_key 在 laravel easy wechat 里有保存么?

createToken 时报错:Trying to get property of non-object

再次执行

 php artisan passport:install

即可解决 (即在数据库中又生成了一个 Laravel Personal Access Client 记录)

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式

谈笑风生

JimmyAnn

请问大神 有这方面的demo吗

大象腿

按照官方文档来就行,demo 懒得写。。。

Nixus

如果不使用passport的话,在拿到openid和session_key之后,openid保存到数据库,session_key保存到redis,这种方案可行吗?
觉得太简单了,不放心

大象伯伯

其实完全可以,passport 的机制就是在数据库维护 token。session_key 不需要存储,只需要自己生成一个 token 存到 redis 里就可以。