登录授权

登录授权

1.本章目标

1.1 目标

读取微信授权

提交数据给后台

接收后台返回数据

记录信息至微信缓存

1.2 重点

读取微信授权

传递数据至后台

1.3 难点

记录缓存至微信

2.业务流程

2.1 业务流程图

2.2 原型图

2.3 业务描述

扫码进入小程序,自动触发获取用户openid的操作,用户同意授权,传递数据给后台API,后台判断用户信息,把对应数据返回给前台小程序。

3.项目

3.1 构建项目

在上一个章节已经构建好了项目。那么构建好项目之后,且已经在上一个章节咱们已经使用过小程序项目内的app.js文件,已经知道这个文件是小程序的主要文件。

而且在咱们构建好项目之后 IDE 工具会直接生成这个标准文件,且这个 js 文件会包含3个方法。

方法:wx.login(...); 上边已被官方给出注释,是做登陆所使用。

3.2 小程序登录

3.2.1 说明

微信、支付宝、短信、银行卡等等,在登陆的过程中已经由微信的官方控制了用户准确性,在现实生活中微信与支付宝都已经可以作为短信一样去作为用户的身份识别唯一码,这里不需要再对用户做身份验证,在微信生态体系内,咱们需要做的就是记录用户的身份。每一个微信账户都有自己的唯一码,而官方允许小程序去去读取用户的唯一码,在微信内叫做openid。

小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。

官方所提供的用户身份试别时许图如下:(时序图观看方式由上至下)

3.2.2 补充
  1. 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
  2. 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 、 用户在微信开放平台帐号下的唯一标识UnionID(若当前小程序已绑定到微信开放平台帐号) 和 会话密钥 session_key

之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

3.2.3 注意事项
  1. 会话密钥 session_key 是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥
  2. 临时登录凭证 code 只能使用一次

3.3 获取用户信息

3.3.1 思路

第一步

利用app.jsonLaunch()方法,点开小程序即加载。

利用微信小程序提供的API:wx.login() 获取用户的code。

如下所示

 //1. 获取code(登录凭证,用来换取openid及session_key等)
    wx.login({
      success: function(res){
         if(res.code){
             that.getNeededUserInfo(res.code);
          }else{
          console.log('获取用户登录态失败!'+res.errMsg);
      }
    }
  })
第二步

把对应的数据传递给后台server由后台server向微信服务器发出GET请求获取对应的session_key。

如下所示

 //2. 获取用户信息(利用wx.login返回的code获取用户的信息)
  getNeededUserInfo: function (code){
    wx.request({
      url: this.globalData.baseUrl+'/sell/getUserInfo',
      method: 'POST',
      data: {
        code: code // 后端通过这个code去调用微信的接口(https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code),传入参数code、appid、appsecret后获取到微信返回的unionid、openid及session_key等。(然后后端可以直接利用微信返回的信息去关联用户在自己网站的user_id)
      },
      success: function(res){
               console.log(res);
        // 可以返回前端需要的用户信息(包括unionid、openid、user_id等)
      }
    })
  }
第三步

获取后台传来的传来的JSON存储在小程序缓存之中,类似于浏览器的cookie之中。

官方提供的API:auth.code2Session

请求地址
GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
请求参数
属性 类型 默认值 必填 说明
appid string 小程序 appId
secret string 小程序 appSecret
js_code string 登录时获取的 code
grant_type string 授权类型,此处只需填写 authorization_code
返回值

Object

返回的 JSON 数据包

属性 类型 说明
openid string 用户唯一标识
session_key string 会话密钥
unionid string 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回,详见 UnionID 机制说明
errcode number 错误码
errmsg string 错误信息
errcode 的合法值
说明 最低版本
-1 系统繁忙,此时请开发者稍候再试
0 请求成功
40029 code 无效
45011 频率限制,每个用户每分钟100次
40226 高风险等级用户,小程序登录拦截 。风险等级详见用户安全解方案

3.3.2 补充

修改APPID

APPID和secret必须与后端的一致否则会报错 40163,40029等等。

修改APPID

修改APPID

修改

查看APPID

查看 AppSecret

以前版本可以直接查看,现在新的版本必须重置才可以查看。

注意

api.weixin.qq.com 不能被配置为服务器域名。开发者应在后端服务器使用getAccessToken获取 access_token,并调用相关 API;

3.3.3 请求IP

微信请求后台的IP不能是本地IP和localhost,所以需要设置不验证IP。

3.4 缓存

3.4.1 一致性

不管前端开发人员还是后端开始人员,只要提起来前后端数据的一致性,怎么来做到识别我是我,肯定第一个想到的就是session,但是小程序与前后端一体化同属于同一个项目是有很大的不同的,小程序所属的项目是微信。那么跟咱们的后端项目是否会具有产生session?答案肯定是否定的。微信本身就是一个项目,咱们的后台也是一个项目,项目与项目之间会产生会话,但是这个会话并没有交给 微信 这个项目下的 小程序。

小程序内是没有session的。

3.4.2 数据缓存

为了解决会话问题,微信给出的解决方案是本地缓存。模拟安卓、IOS等系统所完成的一套方案。

类似于 Cookie 或者 Session 的缓存机制,通过这个本地缓存,我们可以实现很多功能,而且没有 Cookie 或者 Session 那么多限制。

这里可以通过调用wx.setStorageSync与wx.setStorage来完成。

分别是同步缓存和异步缓存。

  • 同步缓存就是必须要同步方法处理完,程序才能继续向下执行。
  • 异步方法无论方法执行成功与否,都会继续向下执
wx.setStorage

是微信小程序异步缓存方法:

是一个获取缓存值异步方法,参数object包含Key,data和success(即缓存成功)、fail(缓存失败)、complete(即缓存完成)3个通用方法。只要是异步的方法都会有这3个通用方法。优点:将过程细化,在3个过程(3个通用方法)中可以进一步优化一功能。

wx.setStorage(OBJECT) 将数据存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容
wx.setStorage({
  key:"key",
  data:"value"
})

wx.getStorage(OBJECT) 从本地缓存中异步获取指定 key 对应的内容。
wx.getStorage({
  key: 'key',
  success: function(res) {
      console.log(res.data)
  }
})

wx.removeStorage(OBJECT) 从本地缓存中异步移除指定 key 。
wx.removeStorage({
  key: 'key',
  success: function(res) {
    console.log(res.data)
  }
})
wx.setStorageSync

是微信小程序同步缓存方法:

是异步获取缓存方法的反向,就是同步获取缓存(所有异步方法后缀加上Sync就是同步方法了)。同步缓存需要接受2个参数。同步方法没有success(即缓存成功)、fail(缓存失败)、complete(即缓存完成)3个通用方法。

wx.setStorageSync(KEY,DATA)
将 data 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个同步接口。

wx.getStorageSync(KEY)
从本地缓存中同步获取指定 key 对应的内容。

wx.getStorageInfoSync
同步获取当前storage的相关信息

wx.removeStorageSync(KEY)
从本地缓存中同步移除指定 key 。

3.4.3 微信小程序本地缓存

每个微信小程序都可以有自己的本地缓存,可以通过 wx.setStorage(wx.setStorageSync)、wx.getStorage(wx.getStorageSync)、wx.clearStorage(wx.clearStorageSync)可以对本地缓存进行设置、获取和清理。

同一个微信用户,同一个小程序 storage 上限为 10MB。localStorage 以用户维度隔离,同一台设备上,A 用户无法读取到 B 用户的数据。其中 localStorage 是持久存储的,但是我们不建议将关键信息全部存在 localStorage,以防用户换设备的情况。

通俗点将就是:本地缓存 localStorage 存在于客户端中,不同用户所对应的缓存数据是相互独立并且因设备而隔离的,而且是持久存储(除非用户清空该小程序的数据)。

过期时间

任何一种缓存都存在过期时间,只不过微信默认的机制是设置了无限长的过期时限,但是对于我们的应用开发中,这确是一个致命的缺陷。

例如我们有一个新闻列表,为了更快的响应用户的请求,更快的加载页面,我们一般把列表缓存到本地,默认情况下如果本地有缓存,我们就不会重新请求 API,但是我们的新闻不可能不更新,更新后的内容就不会显示在小程序中。

其实我们可以参考诸如 Cookie 这样的缓存机制,我们自己创建一个过期时间。在设置某缓存数据 A 的时候,我们可以同时设置一个过期时间值的数据缓存 B,在下一次打开该页面的时候,不仅需要判断数据 A 是否存在,也需要比较 B 与当前时间,如果符合要求则使用本地缓存的数据 A,否则则重新拉取数据并刷新 A 和 B。

以上逻辑翻译成代码则为如下,首先是拉取服务端数据成功后同时设置两个数据缓存,其中 1800000 则是 1800s,当用户进入该页面时,进行缓存数据判断:

var timestamp = Date.parse(new Date());var expiration = timestamp + 1800000; //缓存30分钟var data_expiration = wx.getStorageSync("data_expiration");if (data_expiration) {  if (timestamp > data_expiration) {    wx.clearStorageSync()    wx.setStorageSync("data_expiration", expiration)  }} else {  wx.setStorageSync("data_expiration", expiration)}

首先获取当前的时间戳 timestamp,将其加一个缓存的时间,这里设置为 30 分钟,第二次进入页面的以当前的时间戳和缓存的时间戳比对,如果当前时间戳大于缓存的时间戳,就清除缓存并设置新的缓存过期时间。

wx.getStorageSync() 方法是获取本地缓存,如果没有这只或者为空,则返回 False,所以我们先用 If 判断是否设置了缓存时间 data_expiration,如果设置了就判断时间差。

3.4.4 项目内

在server返回数据后缓存进入微信小程序作为唯一识别码,可以起到类似于session的效果。

在成功的位置加入 缓存的操作:

wx.getStorageSync(res.data.openid);

  getNeededUserInfo: function (code){
    wx.request({
      url: this.globalData.baseUrl+'/sell/getUserInfo',
      method: 'POST',
      data: {
        code: code // 后端通过这个code去调用微信的接口(https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code),传入参数code、appid、appsecret后获取到微信返回的unionid、openid及session_key等。(然后后端可以直接利用微信返回的信息去关联用户在自己网站的user_id)
      },
      success: function(res){
               // 可以返回前端需要的用户信息(包括unionid、openid、user_id等)
               console.log(res);
                //缓存用的openid
               wx.getStorageSync(res.data.openid);
      }
    })
  },

4.总结

此部分完成了登录的操作,这也是微信相关产品开发的正式接触和开始部分。微信生态体系、支付宝生态体系、头条、抖音等等,都本身是一套大的生态体系。其本身就是一个完整的项目,开放出来很多对应的API给咱们所使用的,使用微信等作为入口,就需要去了解相关的API的使用。从数据管理来说与以往的web开发其实是用很大的不同,这里最明显的体现就是session的问题。这里也有助于咱们理解到底什么是项目,项目与项目之间的关系到底如何体现的,都可以做到什么程度等等。如果能够有所领悟本章目的也就完成了。

posted @ 2023-11-14 13:32  SmallMingr  阅读(109)  评论(1)    收藏  举报