由于小程序的登陆和登陆状态维护流程比较复杂,需要客户端和服务器的数次交互以及服务器端的相应处理,很多同学都觉得比较麻烦,所以特别写下这篇博客为大家梳理一下微信的登陆流程,同时加深对微信小程序与登陆状态有关的登陆态标识,用户数据解密,数据校验等具体实现的了解。


首先来说明一下微信的登陆和登陆状态标识实现的流程。

一.小程序登陆和登陆状态维护

微信登陆的主要步骤如下:

1. 调用 wx.login() ,成功后取得返回参数 code,用于后续换取 session_key.

2. 调用 wx.request() 将 code 发送到服务器

3. 服务器将 code 和存储在服务器的 appid 和 appscret 三个参数一起,向下面的微信服务器接口发起请求:

  https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code

获得返回参数 openid 和 session_key 。

请求url中的参数对应上文提到的三个参数。返回的openid是用户唯一标识,session_key 是针对用户数据进行加密签名的密匙
session_key在文件校验,获取用户信息时均需使用


4.服务器使用 openid 和 session_key 生成 3rd_session 作为自己派发的登陆态标识,将其发送到小程序客户端。

       ps.在生成 3rd_session 时,将 3rd_session 作为键,将 session_key + openid 作为值,存储在 服务器的 session 存储中。每个3rd_session都需要设置一个失效时间。

5.小程序客户端将 3rd_session 存入 storage

6.后续用户进入小程序时,首先调用 wx.checksession() 检测登陆态,如果失败,重新发起登陆流程。

7.如果登陆状态未失效,则从 storage 中读取 3rd_session。在需要用户标识的 wx.request() 请求时作为用户标识发送到服务器检验,服务器将其作为索引查找合法的 openid 和 session_key。


获取用户信息

根据wx.getUserinfo()请求参数withCredentials的布尔值及用户的登陆状态,api会有不同的返回值。

  1. 当withCredentials 为 true 且 用户登陆态未到期,返回的数据会包括 encryptedData,iv等敏感数据。

返回数据如下:

  1. userinfo 不包含敏感数据的用户信息
  2. rawData 不包含敏感数据的原始数据字符串,用于签名校验
  3. signature。 使用sha1( rawData + sessionkey ) 得到的字符串,用于签名校验数据完整性
  4. encryptedData 包含 openId,unionId 等用户敏感数据的加密数据
  5. iv 加密算法的初始向量

  6. 当withCredentials 为 false 时,不要求登陆状态,返回数据不包含敏感数据,即不包含上文提到的 encryptedData 和 iv。


微信的数据签名校验

需要使用session_key。开发者将 signature 和 rawData 发送到服务器,服务器通过相同的 sha1( rewData + sessionkey) 算法计算出 signature2,并与signature对比,校验数据完整性。


加密数据的解谜

需要在服务器使用 appId 和 session_key ,根据 iv 对 encryptedData 进行解密,对encryptedData解密后可获得用户的unionId,用于标识用户在微信平台如公众号,小程序等中的唯一用户Id,(微信提供有后端解密代码供使用,有node.js ,c++,python, php,无JAVA)

posted on 2017-07-14 09:54  baraka  阅读(753)  评论(0编辑  收藏  举报