实现微信小程序手机号一键登录的流程涉及到微信小程序端、后端服务器(这里以ThinkPHP6为框架)、以及微信的开放平台服务。下面我将分步骤详细说明这个流程,并提供关键代码示例。
在小程序中,使用wx.login
获取临时登录凭证code,然后调用微信提供的wx.getUserProfile
和wx.getPhoneNumber
接口获取用户信息和加密的手机号。
// app.js 或 页面的onLoad中
wx.login({
success: (res) => {
if (res.code) {
// 发送 res.code 到后台换取 openId, sessionKey
getApp().globalData.code = res.code; // 保存code全局变量,用于后续请求
} else {
console.log('登录失败!' + res.errMsg);
}
}
});
// 在需要获取手机号的页面
wx.getPhoneNumber({
success: (res) => {
const encryptedData = res.encryptedData;
const iv = res.iv;
// 发送 encryptedData, iv, code 到后端解密
this.$api.loginWithPhone({ encryptedData, iv, code }).then(res => {
console.log(res);
});
},
fail: (err) => {
console.log(err);
}
});
通过前端传来的code
,后端向微信服务器请求,获取用户的SessionKey和OpenID。
// 假设你有一个WechatService类来处理微信相关的逻辑
public function getSessionKeyAndOpenid($code)
{
$url = "https://api.weixin.qq.com/sns/jscode2session";
$params = [
'appid' => config('wechat.mini_program.app_id'),
'secret' => config('wechat.mini_program.secret'),
'js_code' => $code,
'grant_type' => 'authorization_code',
];
$response = json_decode(file_get_contents($url . '?' . http_build_query($params)), true);
if (isset($response['errcode'])) {
throw new Exception($response['errmsg']);
}
return $response;
}
使用上一步得到的SessionKey解密前端传来的encryptedData
和iv
,得到手机号。
use EasyWeChat\Kernel\Support\Encryptor;
public function decryptPhoneNumber($encryptedData, $iv, $sessionKey)
{
$decryptor = new Encryptor($sessionKey);
$decrypted = $decryptor->decryptData($encryptedData, $iv, config('wechat.mini_program.app_id'));
return $decrypted['purePhoneNumber'];
}
根据解密后的手机号,在数据库中查找或创建用户,并生成相应的Token返回给前端。
public function loginWithPhone($data)
{
$sessionKey = $this->getSessionKeyAndOpenid($data['code'])['session_key'];
$phoneNumber = $this->decryptPhoneNumber($data['encryptedData'], $data['iv'], $sessionKey);
// 查询或创建用户逻辑...
// 简化示例,实际应包含错误处理等
$user = UserModel::where('phone', $phoneNumber)->first();
if (!$user) {
$user = UserModel::create(['phone' => $phoneNumber]);
}
// 生成Token,这里简化处理,实际可以使用JWT等
$token = md5($user->id . time());
return ['token' => $token];
}
前端收到Token后,可以将其存储在本地,作为后续请求的身份验证凭据。
注意:以上代码仅为示例,实际开发中需考虑异常处理、安全性(如HTTPS、数据验证)、以及详细的错误信息返回等。同时,生产环境中建议使用成熟的JWT或其他认证机制来生成和验证Token。