开发微信小程序时,接入小程序的授权登录可以快速实现用户注册登录的步骤,是快速建立用户体系的重要一步。这篇文章将介绍 python + flask + 微信小程序实现用户快速注册登录方案(本文主要进行后端逻辑的梳理,小程序端逻辑只写了必要的部分,如有需要,请点击连接阅读官方开发文档)

官方给出的微信小程序登录时序图如下:

这个流程分为两大部分:

小程序使用 wx.login() API 获取 code,并由开发者后端服务器换取open_id 和 session_key,小程序使用 wx.getUserInfo() API 获取 encryptedData 和 iv,然后将这三个信息发送给开发者服务器服务器。

开发者服务器获取到 code、encryptedData和 iv 后,将 session_key 利用 encryptedData 和 iv 解密,在服务端获取用户信息。根据用户信息返回 jwt 数据,完成登录状态。

小程序登录流程梳理

1 小程序端调用wx.login

小程序通过

返回值

属性

类型

说明

code

String

用户允许登录后,回调内容会带上 code(有效期五分钟)

2 判断用户是否授权

小程序端可以通过 wx.getSetting 接口获取用户当前的授权状态

如果用户已经授权,则直接发起登录请求

如果用户没有授权,则调用 wx.authorize 或 引导用户关注公众号 来获得授权。

如果用户不予授权,则登录失败。

3 小程序端访问 wx.getUserInfo

小程序端调用

接口success 时返回参数如下:

参数名

类型

说明

userInfo

OBJECT

用户信息对象,不包含 openid 等敏感信息。

rawData

String

不包括敏感信息的原始数据字符串,用于计算签名。

signature

String

使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息

encryptedData

String

包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法

iv

String

加密算法的初始向量,详细见加密数据解密算法

将这些第一步获得的js_code和这里获得的 rawData, signature, encryptedData, iv一起打包传入开发者后端。

4 开发者服务器访问code2session

开发者服务器接收到 code 之后,会进行封装处理,通过session_key和 openid 和 unionid。

准确来说session_key才是真正的微信登录态信息,但是把 openid 和 unionid加起来一起理解,也可以笼统地理解为这些都是微信的登录态信息。

请求参数

属性

类型

默认值

必填

说明

appid

string

小程序 appId

secret

string

小程序 appSecret

js_code

string

登录时获取的 code

grant_type

string

授权类型,此处只需填写 authorization_code

返回值(返回JSON数据包)

属性

类型

说明

openid

string

用户唯一标识

session_key

string

会话密钥

unionid

string

用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回

errcode

number

错误码

errmsg

string

错误信息

这时,服务器需要判断返回的JSON数据包是否包含unionid:

如果包含,则说明用户已经授权(关注过同一主体公众号,或者已经登录过小程序在后端保存unionid)

如果不包含,返回第1步,提醒用户授权

5 开发者服务器校验用户信息

encryptedData 解密后为以下 json 结构,详见加密数据解密算法

{

"openId": "OPENID",

"nickName": "NICKNAME",

"gender": GENDER,

"city": "CITY",

"province": "PROVINCE",

"country": "COUNTRY",

"avatarUrl": "AVATARURL",

"unionId": "UNIONID",

"watermark":

{

"appid":"APPID",

"timestamp":TIMESTAMP

}

}

数据签名校验

为了确保开放接口返回用户数据的安全性,微信会对明文数据进行签名。开发者可以根据业务需要对数据包进行签名校验,确保数据的完整性。

通过调用 wx.getUserInfo 借口获取数据时,接口会同时返回 rawData、signature,其中 signature = sha1( rawData + session_key )

数据签名校验具体步骤

如果 code 为空,返回登录失败。

如果 code 不为空,且 rawData 不为空,需要进行签名校验:

使用 code,appid、app_secret 请求code2session接口获得 session_key 和 openid

如果接口失败,响应 ERR_SESSION_KEY_EXCHANGE_FAILED

使用签名算法通过 rawData 和 session_key 计算签名 signature2

对比 signature 和 signature2

签名不一致,响应 ERR_UNTRUSTED_RAW_DATA

签名一致,解析 rawData 为 wxUserInfo

把 openid 写入到 wxUserInfo

把 (code, wxUserInfo) 缓存到 Redis

更新用户数据库信息(unionid为pk)

进入下一环节

如果 code 不为空,但 rawData 为空,从 Redis 根据 code 查询缓存的用户信息

找到用户信息,进入下一环节

没找到用户信息(可能是过期),响应 ERR_SESSION_EXPIRED

6 生成自定义登录状态(使用JWTtoken)

开发者服务器需要自己生成一个自定义的登录态(例如业务 token或者 session)来保存这些微信服务器返回来的微信登录态相关信息(session_key和 openid 和 unionid),并且做关联处理,然后返回给小程序客户端。

关联处理就是你的自定义登录态和微信的登录态相关联,这样的话就不需要维护多个登录态,只需要维护一个就可以了。

关联处理之后需要将这个自定义登录态信息保存起来,可以放到数据库或者本地文件或者 例如 redis 之类的缓存服务里面,以便方便后续使用,而不需要每次都请求微信服务器(微信服务器对这个请求的频率是有限制的)。

自定义登录态的信息不仅可以包含 token,也可以包含一些用户权限信息,或者其他信息,因为是自定义的登录态,维护也是很自定义的。

7 小程序端将服务器端生成的token储存

小程序客户端接收到返回的自定义登录态信息,从而判断用户是否登录成功,登录成功的话,就将自定义登录态信息保存到本地的存储。到这里,登录就完成了。

本地的存储可以是微信小程序提供的 app.globaldata,也可以是 localstoage,注意,小程序不支持 cookie。

保存到本地存储的好处就是,后续使用的这个自定义登录态就不需要再次跟服务器进行交互来获取了,只需要调用本地存储就行了,这里是为了优化性能和避免浪费资源。

8 小程序访问业务接口逻辑

小程序客户端访问业务接口的时候,携带之前保存到本地存储的自定义登录态信息进行对开发者服务器(业务接口服务器)访问。

开发者服务器的业务接口接收到请求,并且请求里面携带了自定义的登录态,通过校验之后,会返回相关信息。

校验登录是将小程序客户端携带过来的自定义登录态和开发者服务器缓存起来的自定义登录态进行对比,会去确认是否和用户的 openid或者 unionid 和 session_key 相匹配。

如果匹配,就可以马上返回业务信息。

如果不匹配,告知小程序客户端无法访问业务接口,要求用户重新登录。

如果匹配结果是自定义登录态超时了,告知小程序客户端需要重新运行登录逻辑。

如果是匹配结果是自定义登录态没有超时,但是微信登录态超时了,那么要求开发者服务器就会再次发起code2Session进行微信登录态更新。

由于我们的小程序使用微信号作为小程序的账号,如果需要使用自定义的账号,则需要再加上注册的api和关联账号的逻辑。

流程总结

code 是微信用户的登录临时凭证,是打开小程序登录的时候获取的只属于这个微信用户的登录凭证,需要注意的是,这个登录凭证只供微信小程序使用的。且同一个每一次登录时获得的code都不同。这个 code 的存活时间一般是5分钟左右,他的最大作用就是确定是来源自哪一个微信用户来打开,是为了后续生成一个微信登录态 session_key而准备的。

session_key 是微信用户在小程序里面的登录态信息,这是微信给这个用户颁发的一个登录 session。这个session 一直存活直到你关闭小程序。

以前官方是返回固定的 expire_time 的,但是后面取消了,官方的解释是:用户越频繁使用小程序,session_key有效期越长,初始有效期是3天,但是这个不一定是固定的,具体看业务需求,总的原则就是维护一个自定义登录态,自定义登录需要和微信登录态关联。

openId ,用户在微信里面的唯一标识,但是需要跟 unionid 进行一起理解。

unioinId,如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括小程序),用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。

一般来说,openId 就是微信用户的唯一标识,但是因为微信产品很多,所以会出现多个微信产品使用不同的 openId 来识别同一个用户,所以建议是统一使用 unioinid 作为用户识别的依据,因为一般来说,一般的业务都会有公众号,所以 unionid 使用频率较高。

3rd_session 是一般是指开发者服务器的登录态,本文中并没有使用这个概念,而是叫做自定义登录态或者直接说JWTtoken,官方文档或者其他一些博客中会提到它。实际上他们是相同的概念。

当小程序登录态过期了,自定义登录态没过期的时候,那么就需要在小程序打开的时候先执行一次wx.checkSession来检查,如果过期了,就本地执行登录操作,再让开发者服务器跟微信服务器交互,获取新的小程序登录态,然后关联到自定义登录态。

当小程序登录态没过期,自定义登录态过期了的时候,那么小程序客户端访问业务接口的时候,业务接口会告诉小程序客户端,你的自定义登录态超时了,然后小程序客户端会重新执行登录逻辑,然后通知开发者服务重新生成新的自定义登录态,然后关联之前还在使用的小程序登录态。

当二者都同时过期的时候,那就肯定要发起完整的重新登录了。

这样的好处是自定义登录态不需要重复创建,也能跟小程序登录态一起维护管理,达到资源合理利用的效果。

一般自定义登录态的管理都会使用类似 redis 之类的东西来进行管理的,这里也涉及到一个自定义登录态的缓存策略,缓存起来,在一定时间内不需要重新创建自定义登录态,达到优化性能的效果。

登录态的验证

1 在每一次开启小程序的时候需要检查登录态

如果每次打开小程序都需要用户来登录显然是不合适的,如果用户上一次的登录态还没有过期,则应该视用户为已经登录。如果过期,才需要用户重新登录。

有2种方式来做:

方式一:小程序打开的时候先检查小程序本地是否有存储的自定义登录态,

如果没有,则代表是首次登录,要自动执行完整的登录流程,

如果有,则需要判断这个自定义登录态是否过期,可以是开发者服务器提供一个接口来检查,也可以是在这个自定义登录态数据里面加上过期时间,判断是否过期。

过期,则自动发起完整的登录流程。

不过期,就继续使用本地保存的自定义登录态。

方式二:小程序打开的时候先发起wx.checkSession检查微信登录态是否过期:

如果过期,则发起完整的登录流程。

如果不过期,则继续使用本地保存的自定义登录态。(如果本地的自定义登录态没有的话,那么也是要强制发起完整的登录流程的)

2 在每次业务请求时需要验证登录态

某些业务需要只有用户登录状态下才可以执行,所以,我们需要封装一个api来验证用户时候登录

实际上就是检查一下微信和自定义的登录态是否过期

参考链接

微信小程序python flask后端_Flask与微信小程序登录(后端)相关推荐

  1. python flask实战订餐系统微信小程序-60nginx + uwsgi 实现多进程访问

    python flask实战订餐系统微信小程序-60nginx + uwsgi 实现多进程访问 B站配套视频教程观看 uwsgi多进程配置 uwsgi.ini配置 nginx和uwsgi通过配置文件s ...

  2. python flask实战订餐系统微信小程序-59flask部署单进程启动服务

    欢迎关注原创 Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn. ...

  3. flask ajax小程序,Python Flask 搭建微信小程序后台详解

    后台程序返回了数据后,第三步就是小程序该怎么接收返回数据并进行相关业务逻辑处理. 小程序接收返回数据.Python-Flask向小程序返回了JSON格式的数据后,小程序的wx.requset()函数里 ...

  4. 微信小程序python人工智能回复_python实现微信小程序自动回复

    本文是使用Python的itchat模块进行微信私聊消息以及群消息的自动回复功能,必须在自己的微信中添加微信号xiaoice-ms(微软的微信机器人)才能实现,直接复制代码运行之后扫一扫二维码即可,经 ...

  5. 使用Python+Flask+OpenCV构建一个相机应用程序

    前言 在这篇博文中,我们将使用 Flask 框架构建一个相机应用程序,我们可以在其中单击图片.录制视频.应用诸如灰度.负片和"仅人脸"之类的滤镜,就像出现在 Snapchat 上的 ...

  6. 微信小程序+Python Flask后端实战开发案例

    微信小程序安装 因为作者操作系统是Ubuntu16.04 所以在安装小程序开发平台时也踩了不少坑 首先 下载项目和初始化 git clone https://github.com/cytle/wech ...

  7. python flask实战订餐系统微信小程序-00课程介绍及项目演示

    讲课流程 从管理员后端到小程序会员端,按照功能展开讲解 核心代码同步编写,重点代码反复分析讲解 建议大家按顺序观看视频 课程收获 主流的Python3 火爆的小程序 Centos云主机部署 搭建高可用 ...

  8. Python flask实战订餐系统微信小程序-19后台管理员模块数据库创建

    B站配套视频教程观看 第一个要实现的功能是登录退出功能,任何一个大的系统都是有小模块组成的,我们可以通过思维导图整理出模块的功能列表,我们根据思维导图慢慢实现,就可以做出一个由简单到复杂的系统. 后台 ...

  9. python flask实战订餐系统微信小程序-54删除购物车以及下单页面跳转功能实现

    B站配套视频教程观看 动态计算价格 index.js ,totalPrice: function () {var list = this.data.list;var totalPrice = 0.00 ...

  10. python flask实战订餐系统微信小程序-61申请免费https证书

    B站配套视频教程观看 强行关闭nginx yum install -y psmisc fuser -n tcp 80 kill -9 端口号 创建目录存放所有的ssl文件 mkdir /home/ww ...

最新文章

  1. 条件限制select into_SQL全部知识点(夺回控制台掌控权,转义符,SELECT特定列,AND,OR,查询数值,比较运算)...
  2. 二值化每个特征,微软用1350亿参数稀疏神经网络改进搜索结果
  3. ScrollView 里面捕获OnTouchMove事件
  4. Redis 配置文件杂项。
  5. 数据结构基础_二分法查找
  6. 让人耗尽脑汁的需求分析工作(转--Fireball)
  7. radar nyoj 287
  8. 完整记录一则Oracle 11.2.0.4单实例打PSU补丁的过程
  9. H5互动游戏营销方案策划
  10. 工业产品生产许可证审查费用已取消
  11. MySQL查询某一天数据
  12. IM 去中心化概念模型与架构设计
  13. 浅谈面试中常提到的乐观锁与悲观锁
  14. php-fpm 多核,linux 多核CPU性能调优
  15. GUI用户图形界面:GUILayout控件及使用例子
  16. 【C++】洛谷P1873 [COCI 2011/2012 #5] EKO / 砍树
  17. 天池 入门赛-新闻文本分类-单个bert模型分数0.961
  18. 某公司服务器故障导致数据库文件丢失的恢复过程
  19. 精品内容永不过时,个人站长应自我审视
  20. Python获取代理池和提取可用IP

热门文章

  1. 台风怎么看内存颗粒_【内存篇】能否Deja Vu?海力士DJR超频测试
  2. PS2游戏Android模拟器,安卓PS2游戏大全|安卓PS2模拟器游戏_小鸡模拟器
  3. CAD一键统计所有线段长度
  4. SGX软硬件栈(零)——基本介绍
  5. Android app语言中英文转换、多语言转换
  6. 【黑帽SEO案例分析】10天爱站从0到6
  7. 2019年终总结与展望
  8. 基于matlab测量物体直径,基于MATLAB的不规则面积图像测量
  9. 爱奇艺开源FASPell项目
  10. 蓝桥杯-模拟风扇控制系统