微信小程序示例一笔到底 – weapp-demo-session

微信小程序示例 – 一笔到底

微信小程序 提供了一套在微信上运行小程序的解决方案,有比较完整的框架、组件以及 API,在这个平台上面的想象空间很大。

微信的定位并不是 HTML5,这里很多人都有误解。在一些实现上,并不能想当然地用 HTML5 的思路来思考。比如,微信的请求接口wx.request并不支持cookie传递,所以会话层不能使用传统的 Session 方式。

这篇文章分享一个简单的画图应用,使用自己新鲜出炉的小程序会话管理能力来判断并当前用户的身份。

小程序非常简单,使用 Canvas 绘图后,把序列化的actions提交给服务器保存。下次加载的时候,再列出用户曾经绘制过的图。

部署和运行

拿到了本小程序源码的朋友可以尝试自己运行起来。

整体架构

1. 准备域名和证书

在微信小程序中,所有的网路请求受到严格限制,不满足条件的域名和协议无法请求,具体包括:

  • 只允许和在 MP 中配置好的域名进行通信,如果还没有域名,需要 注册一个 。
  • 网络请求必须走 HTTPS 协议,所以你还需要为你的域名 申请一个证书 。

域名注册好之后,可以登录 微信公众平台 配置通信域名了。

2. 云主机和镜像部署

一笔到底的服务器运行代码和配置已经打包成腾讯云 CVM 镜像,大家可以 直接使用 。

腾讯云用户可以 免费领取礼包 ,体验腾讯云小程序解决方案。

镜像已包含所有小程序的服务器环境与代码,需要体验其它小程序的朋友无需重复部署

3. 配置 HTTPS

镜像中已经部署了 nginx,需要在/etc/nginx/conf.d下修改配置中的域名、证书、私钥。

配置完成后,即可启动 nginx。

nginx

4. 域名解析

我们还需要添加域名记录解析到我们的云服务器上,这样才可以使用域名进行 HTTPS 服务。

在腾讯云注册的域名,可以直接使用 云解析控制台 来添加主机记录,直接选择上面购买的 CVM。

解析生效后,我们在浏览器使用域名就可以进行 HTTPS 访问。

5. 配置云存储 Redis

会话管理依赖 Redis 进行作为缓存管理,开发者可以选择自行搭建 Redis 服务或者直接购买 云存储 Redis 服务 。

6. 配置云数据库 MongoDB

一笔到底小程序使用 MongoDB 来存储用户绘制的图像路径,要运行小程序开发者需要自行搭建 MongoDB 服务或者直接购买 云数据库 MongoDB 。

7. 启动一笔到底示例 Node 服务

在镜像的 nginx 配置中(/etc/nginx/conf.d),已经把/applet/session的请求转发到http://127.0.0.1:5757处理。我们需要把 Node 服务运行起来。Node 代码部署在目录/data/release/qcloud-applet-session下。

进入该目录:

cd /data/release/qcloud-applet-session

在该目录下有个名为config.js的配置文件(如下所示),根据注释将appId、appSecret、redisConfig、mongoConfig修改成自己的配置。

module.exports = {
    port: '5757',
    ROUTE_BASE_PATH: '/applet',

    // 微信小程序 App ID
    appId: '',

    // 微信小程序 App Secret
    appSecret: '',

    // Redis 配置
    // @see https://www.npmjs.com/package/redis#options-object-properties
    redisConfig: {
        host: '',
        port: '',
        password: '',
    },

    // MongoDB 配置
    // @see https://www.qcloud.com/doc/product/240/3979
    mongoConfig: {
        username: '',
        password: '',
        host: '',
        port: '',
        query: '?authMechanism=MONGODB-CR&authSource=admin',
        database: 'qcloud-applet-session',
    },
};

一笔到底示例使用 pm2 管理 Node 进程,执行以下命令启动 node 服务:

pm2 start process.json

实现

会话层实现

会话层实现包含两个部分:

我们的 Demo 直接使用这两个仓库,可以快速地拥有会话层的能力。

会话层的实现和传统 Cookie 的实现方式类似,都是在 Header 上使用特殊的字段跟踪。一个请求的完整流程如下:

  1. 客户端(微信小程序)发起请求request
  2. weapp-session-client 包装request
    • 首次请求
      • 调用wx.login()和wx.getUserInfo()接口获得code、rawData和signature
      • requset的头部带上code、rawData和signature
      • 保存code供下次调用
    • 非首次请求
      • request的头部带上保存的code
  3. 服务器收到请求request,中间件从头部提取code、rawData和signature字段
    • 如果code为空,跳到第4步
    • 如果code不为空,且rawData不为空,需要进行签名校验
      • 使用code,appid、app_secret请求微信接口获得session_key和openid
        • 如果接口失败,响应ERR_SESSION_KEY_EXCHANGE_FAILED
      • 使用签名算法通过rawData和session_key计算签名signature2
      • 对比signature和signature2
        • 签名一致,解析rawData为wxUserInfo
          • 把openid写入到wxUserInfo
          • 把(code, wxUserInfo)缓存到 Redis
          • 把wxUserInfo存放在request.$wxUserInfo里
          • 跳到第4步
        • 签名不一致,响应ERR_UNTRUSTED_RAW_DATA
    • 如果code不为空,但rawData为空,从 Redis 根据code查询缓存的用户信息
      • 找到用户信息,存放在request.$wxUserInfo字段里,跳到第4步
      • 没找到用户信息(可能是过期),响应ERR_SESSION_EXPIRED
  4. request被业务处理,可以使用request.$wxUserInfo来获取用户信息(request.$wxUserInfo可能为空,业务需要自行处理)

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:微信小程序示例一笔到底 – weapp-demo-session