开发微信小程序时,接入小程序的受权登陆能够快速实现用户注册登陆的步骤,是快速创建用户体系的重要一步。这篇文章将介绍 python + flask + 微信小程序实现用户快速注册登陆方案(本文主要进行后端逻辑的梳理,小程序端逻辑只写了必要的部分,若有须要,请点击链接阅读官方开发文档)html
官方给出的微信小程序登陆时序图以下:python
这个流程分为两大部分:redis
小程序经过**wx.login**获取微信的 code,而后将这个 code 发送给开发者服务器。算法
返回值数据库
属性 | 类型 | 说明 |
---|---|---|
code | String | 用户容许登陆后,回调内容会带上 code(有效期五分钟) |
小程序端能够经过 wx.getSetting 接口获取用户当前的受权状态json
引导用户关注公众号
来得到受权。小程序端调用 wx.getUserInfo API 来得到用户信息(该接口的调用须要得到用户受权)flask
接口success 时返回参数以下:小程序
参数名 | 类型 | 说明 |
---|---|---|
userInfo | OBJECT | 用户信息对象,不包含 openid 等敏感信息。 |
rawData | String | 不包括敏感信息的原始数据字符串,用于计算签名。 |
signature | String | 使用 sha1( rawData + sessionkey ) 获得字符串,用于校验用户信息 |
encryptedData | String | 包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法 |
iv | String | 加密算法的初始向量,详细见加密数据解密算法 |
将这些第一步得到的js_code
和这里得到的 rawData
, signature
, encryptedData
, iv
一块儿打包传入开发者后端。segmentfault
开发者服务器接收到 code
以后,会进行封装处理,经过**code2Session**这个api接口来获取真正须要的微信用户的登陆态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:
encryptedData
解密后为如下 json 结构,详见加密数据解密算法
{ "openId": "OPENID", "nickName": "NICKNAME", "gender": GENDER, "city": "CITY", "province": "PROVINCE", "country": "COUNTRY", "avatarUrl": "AVATARURL", "unionId": "UNIONID", "watermark": { "appid":"APPID", "timestamp":TIMESTAMP } }
解密脚本实例链接:https://res.wx.qq.com/wxdoc/dist/assets/media/aes-sample.eae1f364.zip
为了确保开放接口返回用户数据的安全性,微信会对明文数据进行签名。开发者能够根据业务须要对数据包进行签名校验,确保数据的完整性。
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)
缓存到 Rediscode
不为空,但 rawData
为空,从 Redis 根据 code
查询缓存的用户信息
ERR_SESSION_EXPIRED
开发者服务器须要本身生成一个自定义的登陆态(例如业务 token或者 session)来保存这些微信服务器返回来的微信登陆态相关信息(session_key
和 openid
和 unionid
),而且作关联处理,而后返回给小程序客户端。
小程序客户端接收到返回的自定义登陆态信息,从而判断用户是否登陆成功,登陆成功的话,就将自定义登陆态信息保存到本地的存储。到这里,登陆就完成了。
app.globaldata
,也能够是 localstoage
,注意,小程序不支持 cookie
。小程序客户端访问业务接口的时候,携带以前保存到本地存储的自定义登陆态信息进行对开发者服务器(业务接口服务器)访问。
开发者服务器的业务接口接收到请求,而且请求里面携带了自定义的登陆态,经过校验以后,会返回相关信息。
校验登陆是将小程序客户端携带过来的自定义登陆态和开发者服务器缓存起来的自定义登陆态进行对比,会去确认是否和用户的 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
来检查,若是过时了,就本地执行登陆操做,再让开发者服务器跟微信服务器交互,获取新的小程序登陆态,而后关联到自定义登陆态。若是每次打开小程序都须要用户来登陆显然是不合适的,若是用户上一次的登陆态尚未过时,则应该视用户为已经登陆。若是过时,才须要用户从新登陆。
有2种方式来作:
wx.checkSession
检查微信登陆态是否过时:
某些业务须要只有用户登陆状态下才能够执行,因此,咱们须要封装一个api来验证用户时候登陆
实际上就是检查一下微信和自定义的登陆态是否过时