微信小程序登录
官方定义:小程序可以通过微信官方提供的登录能力方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。
再来一张官方的配图
从图中不难看出登录流程:
- 小程序内调用
wx.login()
获取code
。 - 小程序内再调用
wx.request()
向服务器(后端接口)发送code
。 - 服务器拿到
code
后向微信服务器发送请求,调用的接口是auth.code2Session
,微信服务器返回openid
和session_key
两个重要值。 - 拿到
openid
和session_key
两个值后,自定义一下登录状态并返回(这个登录状态通常就是token
)。 - 小程序将
token
存储到storage
中,在接下来的业务请求中,带上这个token
即可。
注意事项
因为会话密钥session_key
是对用户数据进行 加密签名 的密钥。所以为了应用自身的数据安全,session_key
必须保存在服务器端,且不可下发到小程序。
小程序端登录
1、2步正常都是同时出现的。
// 先从storage中获取token
const token = wx.getStorageSync('token') || ''
// 如果没有则获取
if (!token) {
// 登录
wx.login({
success: (res) => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
wx.request({
url: `${this.globalData.domain}/api/login`,
method: 'POST',
header: {
ContentType: 'application/json',
Accept: 'application/json'
},
data: {
// 将wx.login()获取的code传递给后端
code: res.code
},
success: (e) => {
// 获取返回数据,并保存token到storage中
if (e.data.code === 200) {
wx.setStorageSync('token', e.data.token)
}
}
})
}
})
}
后端认证
后端拿到code
后,调用auth.code2Session
接口获取openid
和session_key
,后端使用Laravel
,认证方式为sanctum
。
public function login(Request $request)
{
$request->validate([
'code' => 'required'
], [
'code.required' => 'js_code不能为空'
]);
// 这3个值必传
$appid = config('wechat.appid');
$appsecret = config('wechat.appsecret');
$code = $request->input('code');
// auth.code2Session接口的地址
$url = "https://api.weixin.qq.com/sns/jscode2session?appid=$appid&secret=$appsecret&js_code=$code&grant_type=authorization_code";
// GET 方式请求
$response = Http::get($url)->json();
// 如果返回数据中有openid则继续,否则直接返回报错内容
if (isset($response['openid'])) {
// 获取用户,没有则创建
$user = User::firstOrCreate([
'openid' => $response['openid']
], [
'openid' => $response['openid'],
'session_key' => $response['session_key']
]);
// 生成token
$token = $user->createToken($response['openid']);
return response()->json([
'code' => 200,
'msg' => 'success',
'token' => $token->plainTextToken
]);
}
return $response;
}
微信小程序登录可以在用户无感知的情况下完成登录,与传统的登录方式比较,用户体验较好。