微信官方文档
官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
小程序登录
小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。
登录流程时序
说明: 调用wx.login()
获取 临时登录凭证code
,并回传到开发者服务器。调用auth.code2Session
接口,换取 用户唯一标识OpenID
和 会话密钥session_key
。之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。 注意:会话密钥session_key
是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。临时登录凭证code
只能使用一次
小程序登录态
对于小程序来说,也需要一个唯一的标识符来区分用户,也就是session
来保持会话,但是小程序没有cookie
, 因此我们的唯一标识符会被存储在 localstorage
里面,每次发请求时,都会从localStorage
里面拿到这个唯一标识符,带在请求中。
微信的openid和code
在日常开发中,我们也经常听到 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
对应的记录,然后校验有效期
注意:上面提到的
3rd_session
只是一种实现方式,可以自定义登录态。
具体代码实现可以参考 微信小程序实现微信登录
union_id打通公众号与小程序用户体系
需要用到wx.getUserInfo
,https://mp.weixin.qq.com/debug/wxadoc/dev/api/open.html#wxgetuserinfoobject,从小程序端传入$encryptedData
, $iv
到服务端,需要用到官方提供好的解密sdk,https://mp.weixin.qq.com/debug/wxadoc/dev/demo/aes-sample.zip,其中包含了php示例代码,对它简单的复制粘贴如下
// 获取unionid
private function getUnionId($encryptedData, $iv) {
require_once __DIR__ . '/../third_party/aes/wxBizDataCrypt.php';
$appid = 'wxcb935c2ec6734f08';
$pc = new WXBizDataCrypt($appid, $sessionKey);
$errCode = $pc->decryptData($encryptedData, $iv, $data );
if ($errCode == 0) {
$obj = json_decode($data);
var_dump($obj->unionId);
// unset($array["watermark"]);
return [
'unionid' => $obj->unionId,
'nickname' => $obj->nickName,
'avatarUrl' => $obj->avatarUrl,
'gender' => $obj->gender,
'country' => $obj->country,
'province' => $obj->province,
'city' => $obj->city,
'language' => $obj->language
];
} else {
print($errCode . "n");
}
}
这样就得到了unionid,就可以与自己的同一开发平台的帐号体系下的应用打通了,否则不会返回unionid。
其他
cookie 和 session 的区别
cookie 和 session 并不是同一个层面的东西。
cookie
是实际真实存在的一个东西,是http协议规定的,如同一种载体,我们可以在响应头里面设置 cookie,只要你愿意,你可以在cookie里面设置任何东西,不管是用户信息用户昵称, 但是这样有安全性风险,cookie里面不适合有敏感性的信息,比如说,只放session_idsession
是一个抽象概念,是客户端和服务端保持会话的一种方法,一种通用的机制。session 的意思是会话,实现是:服务端把一个唯一标识和用户身份的对应的关系存储下来,存在redis, 文件, 数据库中都可以。客户端出的请求带上唯一标识,服务端从redis 或者 文件或者 数据库中找出这个唯一标识 对应的身份,这种机制就被称为session
session 机制大部分使用cookie 作为载体运送这个唯一标识,也可以采用url 连接、 自定义请求头来实现。
参考文章
微信小程序的登录体系
微信小程序实现微信登录