我们知道,WEB服务器通过浏览器携带的cookie获取session来判断是否是同一用户(或浏览器)。
-
cookie
和session
并不是同一个层面的东西。 -
cookie
是实际真实存在的一个东西,是http协议规定的,如同一种载体,我们可以在响应头里面设置 cookie,只要你愿意,你可以在cookie里面设置任何东西,不管是用户信息用户昵称, 但是这样有安全性风险,cookie里面不适合有敏感性的信息,比如说,只放session_id
-
session
是一个抽象概念,是客户端和服务端保持会话的一种方法�,一种通用的机制。session
的意思是会话
,实现是:服务端把一个唯一标识和用户身份的对应的关系存储下来,存在redis
,文件
,数据库
中都可以。客户端出的请求带上唯一标识,服务端从redis
或者文件
或者数据库
中找出这个唯一标识 对应的身份,这种机制就被称为session
-
session
机制大部分使用cookie
作为载体运送这个唯一标识,也可以采用url 连接、 自定义请求头来实现。
对于小程序来说,也需要一个唯一的标识符来区分用户,也就是session来保持会话,但是小程序没有cookie, 因此我们的唯一标识符会被存储在 localstorage
里面,每次发请求时,都会从localStorage
里面拿到这个唯一标识符,带在请求中。
在日常开发中,我们也经常听到openid
和code
的概念。
openid
用来标识这个唯一的微信用户,也就是说,一个微信用户相对于一个公众号(主体)的openid
是唯一的,是不会变的。
那么我们如何才能知道 某一个用户的 openid
呢?
就是通过code
, 对于同一个用户,每次获取到的 code
都会改变,有有效期。我们把code
作为参数,调用指定的微信服务器的接口,就可以拿到用户的openid
。
那么我们如何才能拿到 code
呢?
微信内h5页面的方法是:跳到指定的微信的承接页面,再跳回到本页面,url链接上就会被拼上code
。
小程序的方法是: 通过调用 wx.login()
方法,就可以拿到用户的code
知道了上面的前提条件,就可以去实现一个微信小程序的登录体系。
-
通过
wx.login()
获取到用户的code
-
通过
wx.request()
方法请求我们自己的�后端,我们自己的服务端把appid
,appsecret
和code
一起发送到微信服务器。appid
和appsecret
都是微信提供的,可以在管理员后台找到 -
微信服务器返回了
openid
-
我们在自己的数据库中,查找
openid
,如果没有查到记录,说明该用户没有注册,如果有记录,则继续往下走 -
我们生成一个第三方session, 也就是session_id, 也就是用户唯一标识符。在redis中,把session_id 和用户的身份存进去。
-
返回
3rd_session
-
小程序把
3rd_session
存到 storage 里面 -
下次请求时,先从
storage
里面读取,然后带给服务端 -
服务端从redis 里面找到
3rd_session
对应的记录,然后校验有效期
问题一:
为什么我们要自己维护一个用户数据库,�实现一个注册体系?用微信的不好吗?
因为我们业务不光是在微信里面玩,比如说,在app的场景下,我们肯定没有办法通过微信这一套来登录。
问题二:
为什么仍需设置前端的登录态,而不是每次用小程序的code换open_id?
因为用code换open_id的方式,需要等待wx.login() 获取code, 需要等待node端请求微信服务器用code换取open_id。 相比于直接直接带上登录态,用户等待时间更长。
最新版小程序中,只需要一个按钮就可以获取到用户的信息
获取头像昵称
微信规定需要指定该btn的open-type
为 getUserInfo
, 用户信息会放在getUserInfo
的回调函数里面。
如果用户之前没有授权过,则会弹出弹窗授权。
如果用户已经授权过,则不需要弹出弹窗授权。
通过 wx.getSetting
方法可以获取到用户的授权信息
wx.getSetting({
success(res) {
if (!res || !res.authSetting) {
wx.showToast({
title: '查询授权失败',
})
return;
}
this.setData({
authInfo: res.authSetting
})
}
})
- 微信小程序没有遇到跨域的问题。�原因:wx.request() 请求其实是先走到了微信服务器,然后微信服务器再请求的第三方服务器,相当于起到了代理服务器的作用。