公司小程序项目中快速登录需要实现微信用户授权手机登录、注册功能。结果遇到了
invalid code hint: [zHkDmt0sf-MBjga] rid: 64e3259f-1091b953-7e10f1da
目录
服务端文档
文档描述
返回信息
服务端代码
遇到问题
排查问题
1.服务端用错了appid serect
2.小程序端用错了appid serect
3.服务端用错了access_token
4.是否存在code使用了多次
5.非指定code
总结
该接口需配合手机号快速验证或手机号实时验证能力一起使用,当用户同意后,可以通过 bindgetphonenumber 或 bindrealtimegetphonenumber 事件回调获取到动态令牌code,再调用该接口将code换取用户手机号。
注意:每个code只能使用一次,code的有效期为5min。
功能流程
这里需要处理小程序发送过来code后,请求小程序手机号验证接口;
参数需要先获取小程序的access_token,和小程序获得的code。
class WeChat
{
/**
* 小程序appid
* @var string
*/
protected static $min_AppId = '你的小程序 appid';
/**
* 小程序app secret
* @var string
*/
protected static $min_AppSecret = '你的小程序secret';
private static $_self;
private function __construct()
{
// TODO: Implement __construct() method.
}
/**
* 外部直接调用静态方法中的实例化
* @return WeChat
*/
public static function getInstance()
{
if (!self::$_self instanceof self) {
self::$_self = new self();
}
return self::$_self;
}
private function __clone()
{
// TODO: Implement __clone() method.
}
/**
* 获取小程序接口调用凭证
* @Author: Yjl
* @Since: 2023/8/21 16:42
* @return mixed
*/
protected function getMiniAccessToken()
{
$APPID = self::$min_AppId;
$SECRET = self::$min_AppSecret;
$url = "https://api.weixin.qq.com/cgi-bin/token?appid={$APPID}&secret={$SECRET}&grant_type=client_credential";
$res = $this->linkCurl($url, 'GET');
$res = djson($res);
if (isset($res['errcode']) && $res['errcode']) {
return [‘status’ => 0,’msg’ => $res['errmsg'],’data’=> ‘’];
}
return [‘status’ => 1,’msg’ => ‘success’,’data’=> $res['access_token']];
}
/**
* 微信小程序-手机号快速验证
* @Author: Yjl
* @Since: 2023/8/21 16:01
* @param $code
* @return mixed
*/
public function getPhoneNumber($code)
{
$res = $this->getMiniAccessToken();
if ($res['status'] != 1) return $res;
$url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" . $res['data'];
$param = ['code' => $code];
$data = json_encode($param);
$header = array();
$header[] = 'content-type:application/json';
$res = $this->linkCurl($url, 'POST', $data, $header);
$res = djson($res);
if (isset($res['errcode']) && $res['errcode']) {
return [‘status’ => 0,’msg’ => $res['errmsg'],’data’=> ‘’];
}
return [‘status’ => 1,’msg’ => ‘success’,’data’=> $res];
}
/**
* 请求接口返回内容
* @param $url :请求的URL地址
* @param $method :请求方式POST|GET
* @param $params :请求的参数
* @param $header : 请求头
* @return bool|string
*/
protected function linkCurl($url, $method, $params = array(), $header = array())
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if (strpos("$" . $url, "https://") == 1) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if ($method == "POST") {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
} else if ($params) {
curl_setopt($ch, CURLOPT_URL, $url . '?' . http_build_query($params));
}
$response = curl_exec($ch);
if ($response === false) {
return false;
}
curl_close($ch);
return $response;
}
}
无效的code
invalid code hint: [zHkDmt0sf-MBjga] rid: 64e3259f-1091b953-7e10f1da
返回截图如下:
经过仔细排查代码内容,此项无问题。
经过前端同事对比,和原有小程序其他接口使用正常,此项可以排除。
因为服务端也有公众号操作,所以发现access_token用混了,改之后还是提示上方错误!
通过前端打印请求日志和直接使用code请求微信接口,此项可排除。
最后继续研究文档才发现此code非彼code;
怎么回事呢,项目中还有一个登录获取用户信息的也需要小程序端生成code,然后服务端去获取用户信息实现登录;跟手机号验证的code不是同一个code,前端给用混了。
文档如下:
步骤1:需要将 button 组件 open-type 的值设置为 getPhoneNumber,当用户点击并同意之后,通过 bindgetphonenumber 事件获取回调信息;
步骤2:将 bindgetphonenumber 事件回调中的动态令牌code传到开发者后台,并在开发者后台调用微信后台提供的 phonenumber.getPhoneNumber 接口,消费code来换取用户手机号。每个code有效期为5分钟,且只能消费一次。
注:getPhoneNumber 返回的 code 与 wx.login 返回的 code 作用是不一样的,不能混用。
发现问题并解决了觉得很简单,但当时真的耽误了一天;为什么开始没发现这个问题,只能说是前后端联调的锅;在这里记录一下吧,之前从网上找解决方法的时候看到很多原因,我这里也提供一种解决思路吧;最后还是要多看文档,多做测试,多沟通。