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

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

官方流程图

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 记录)

谈笑风生

JimmyAnn

请问大神 有这方面的demo吗

大象腿

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

Nixus

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

大象伯伯

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

爱评论不评论

近期节日

2018年09月22日 世界无车日
2018年09月23日 秋分
2018年09月23日 国际聋人节
2018年09月24日 中秋节
2018年09月27日 世界旅游日
2018年10月01日 国庆节
2018年10月04日 世界动物日
2018年10月08日 寒露
2018年10月09日 世界邮政日
2018年10月10日 辛亥革命纪念日
2018年10月13日 中国少年先锋队诞辰日
2018年10月14日 世界标准日
查看更多节日