微信小程序之會話處理

WechatAppSessionBundle 是一個用於處理微信小程序的 Symfony Bundle,實現思路參照了騰訊雲官方-微信小程序雲端解決方案中的 會話管理場景,即這個 Bundle 是其 PHP(Symfony) 版本的一種實現。(只是不知道國內有多少使用 Symfony 的童鞋?)php

微信的定位並非 HTML5,這裏不少人都有誤解。在一些實現上,並不能想固然地用 HTML5 的思路來思考。好比,微信的請求接口 wx.request 並不支持 cookie 傳遞,因此會話層不能使用傳統的 Session 方式。 ——騰訊雲官方的微信小程序雲端解決方案git

該 Bundle 包含的功能:github

  • 針對特定的控制器獲取微信用戶信息並校驗合法性redis

  • 將用戶信息緩存到 Redisjson

  • 將用戶信息設置到 Symfony/Component/HttpFoundation/Request 對象中小程序

安裝和配置

第一步:使用 composer 安裝 Bundle

composer require wechat-app/session-bundle

第二步:啓用 Bundle

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new Sensio\Bundle\BuzzBundle\SensioBuzzBundle(),
        new Snc\RedisBundle\SncRedisBundle(),
        new WechatApp\SessionBundle\WechatAppSessionBundle(),
        // ...
    );
}

第三步:配置依賴 Bundle

相關依賴的深刻配置,請參考其對應的文檔。緩存

第四步:配置

# app/config/config.yml
snc_redis:
    clients:
        default:
            type: predis
            alias: default
            dsn: "redis://passwd@localhost"

wechat_app_session:
    app_id:     "wx66666"   # 小程序的app id
    app_secret: "wx*****"   # 小程序的app secret
    key_prefix: "wx-user:"  # Redis中,用戶信息的key前綴

第五步:使用

在安裝和配置完成以後,Bundle 的功能立刻就能夠投入使用了,該 Bundle 只會對實現了 WechatApp/SessionBundle/Controller/SessionAuthController 接口的控制器生效,對其餘不是用於處理小程序請求的接口不會有影響。bash

處理流程請參照騰訊雲提供的官方文檔

下面舉個例子:

// src/DemoBundle/Controller/DemoController.php
namespace DemoBundle\Controller;

use AppBundle\Controller\BaseController;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use WechatApp\SessionBundle\Controller\SessionAuthController;

/**
 * @Route("/demo")
 */
class DemoController extends Controller implements SessionAuthController
{
    /**
     * @Route("/test")
     */
    public function testAction(Request $request) 
    {
        // 從 Request 的 header 的屬性中獲取當前請求的微信用戶信息
        $wxUser = $request->attributes->get('wx_user');
        return $this->json($wxUser);
    }
}

訪問上面 action 對應的路由,將返回一個包含用戶信息 json,大體是:

{
  "nickName": "MJ",
  "gender": 1,
  "language": "zh_CN",
  "city": "Zhuhai",
  "province": "Guangdong",
  "country": "CN",
  "avatarUrl": "頭像URL",
  "openId": "owVxxxxxxxxxxx"
}

此時登入到 Redis 中:

keys *
1) "wx-user:session:xxxxxxxxxxx"
2) "wx-user:code:owVxxxxxxxxxxx"
  • wx-user:code:*** 維護用戶 openid 對應的 session

  • wx-user:session:*** 保存着對應於前者的用戶信息

以上兩個 key 都設置了過時時間,目前定爲7200秒。

以上是後端接口部分的使用,小程序端的部分相對來講比較簡單。

  • 在首次獲取用戶信息的時候,須要調用 wx.loginwx.getUserInfo 接口,把獲取到的 coderawDatasignature 一同設置到 wx.request 接口的 header 中,設置時,有特定的名稱,分別是 X-WX-CodeX-WX-RawDataX-WX-Signature

  • 接口返回非200的 HTTP 狀態碼時,請查看接口返回的提示信息,若請求成功,則會返回你本身編寫的接口所返回的信息

該 Bundle 暫時沒有提供小程序端的部分,小程序端的實現能夠參考上面的說明去自行實現,或借鑑騰訊雲官方提供的一個實現方式,記住,是借鑑而不是照搬,由於這個 Bundle 並不是是爲了搭配騰訊雲提供的實現方案的,另外要注意的是,其小程序端的實現方式只實現了 wx.request 接口的包裝,而關於文件上傳、WebSocket 的實現都尚未包裝,使用時仍是須要考慮本身完善其餘請求的包裝。

相關文章
相關標籤/搜索