admin 发表于 2020-8-28 14:06:03

Discuz!社区解决微信公众号网页授权域名只能填写一个的问题

Discuz!社区解决微信公众号网页授权域名只能填写一个的问题借权网页授权域名的问题解决方案:
在discuz建站中,必不可少的都会涉及到微信网页授权,来获取用户信息的功能。想要实现公众号通过微信网页授权机制,来获取用户基本信息,必须先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,填写授权回调域名。但是呢,在微信公众号后台,业务域名和JS安全域名都可以填写3个,唯独网页授权域名只能填写一个。

现在我只有一个公众号,由于业务需要,我在不同的场景下不同的域名都使用这个公众号,而且都需要获取用户信息。但是网页授权域名只能填写一个,并且只有回调地址的域名与该设置完全相同,才能成功发起微信授权,否则就会提示rediret_uri参数错误。

那么,就来讲讲怎么突破这个限制,实现多个域名使用一个公众号同时发起网页授权获取到用户基本信息。

它只能填写一个授权域名,那我们就从这一个域名下手,既然这个授权域名可以顺利拿到网页请求的数据,那我们其他的域名可以先去请求授权域名,然后让授权域名再去微信服务器请求数据,这样就完美解决了。这个授权域名,起到了类似于中介和代理人的作用。实现方法如下:
1.在公众号后台设置一个授权回调页面域名,比如叫:wx.agency.com,我们可以称其为代理域名。
2.在wx.agency.com指向的网站根目录下部署一个index.php文件。
工作原理如下:
(1)当你的其他域名需要发起微信授权时,将授权请求先发到代理域名wx.agency.com,然后wx.agency.com会把这个请求转发到微信服务器;
(2)当用户同意授权后,wx.agency.com会收到微信的授权回调,并把回调结果(code、state参数)原封不动地再返回给最开始发起授权的域名。

代码实现:
之前有写过微信网页授权获取用户基本信息,那是常规方法授权获取用户信息,代码如下:

public function _userInfoAuth($redirect_url){
       
        //1.准备scope为snsapi_userInfo网页授权页面
        $redirecturl = urlencode($redirect_url);
        $snsapi_userInfo_url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->_appid.'&redirect_uri='.$redirecturl.'&response_type=code&scope=snsapi_userinfo&state=YQJ#wechat_redirect';
       
        //2.用户手动同意授权,同意之后,获取code
        //页面跳转至redirect_uri/?code=CODE&state=STATE
        $code = $_GET['code'];
        if( !isset($code) ){
                header('Location:'.$snsapi_userInfo_url);
        }
       
        //3.通过code换取网页授权access_token
        $curl = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->_appid.'&secret='.$this->_appsecret.'&code='.$code.'&grant_type=authorization_code';
        $content = $this->_request($curl);
        $result = json_decode($content);
       
        //4.通过access_token和openid拉取用户信息
        $webAccess_token = $result->access_token;
        $openid = $result->openid;
        $userInfourl = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$webAccess_token.'&openid='.$openid.'&lang=zh_CN ';
       
        $recontent = $this->_request($userInfourl);
        $userInfo = json_decode($recontent,true);
        return $userInfo;
}

这次获取用户信息的代码如下:

//第三方代理服务器授权登录
public function agencyInfoAuth($redirect_url){
       
        //1.准备scope为snsapi_userInfo网页授权页面
        $redirecturl = urlencode($redirect_url);
        $snsapi_userInfo_url = 'http://wx.agency.com/index.php?appid='.$this->_appid.'&redirect_uri='.$redirecturl.'&response_type=code&scope=snsapi_userinfo&state=YQJ#wechat_redirect';
       
        //2.用户手动同意授权,同意之后,获取code
        //页面跳转至redirect_uri/?code=CODE&state=STATE
        $code = $_GET['code'];
        if( !isset($code) ){
                header('Location:'.$snsapi_userInfo_url);
        }
       
        //3.通过code换取网页授权access_token
        $curl = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->_appid.'&secret='.$this->_appsecret.'&code='.$code.'&grant_type=authorization_code';
        $content = $this->_request($curl);
        $result = json_decode($content);
       
        //4.通过access_token和openid拉取用户信息
        $webAccess_token = $result->access_token;
        $openid = $result->openid;
        $userInfourl = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$webAccess_token.'&openid='.$openid.'&lang=zh_CN ';
       
        $recontent = $this->_request($userInfourl);
        $userInfo = json_decode($recontent,true);
        return $userInfo;
}


可以看到两种方法唯一的区别就在第一步准备scope为snsapi_userInfo网页授权页面链接不同,一个是去open.weixin.qq.com请求数据,另一个是去wx.agency.com请求数据。
这个方案我亲测有效,虽然增加了一次重定向操作,但实际上不会对用户体验产生多大的影响,真实解决了公众号网页授权域名只能填写一个的问题。

Discuz智能体 发表于 2025-3-20 04:05:45

在Discuz!社区中,解决微信公众号网页授权域名只能填写一个的问题,确实可以通过代理域名的方式来实现。你提供的方案是一个常见的解决方案,通过一个代理域名来中转微信的授权请求和回调,从而绕过微信公众号后台只能设置一个授权域名的限制。

### 具体实现步骤:

1. **设置代理域名**:
   - 在微信公众号后台设置一个授权回调页面域名,比如 `wx.agency.com`,这个域名将作为代理域名。
   - 确保 `wx.agency.com` 指向的服务器能够处理微信的授权请求和回调。

2. **部署代理脚本**:
   - 在 `wx.agency.com` 的网站根目录下部署一个 `index.php` 文件,用于处理微信的授权请求和回调。
   - 这个脚本的主要作用是接收来自其他域名的授权请求,并将请求转发到微信服务器,然后将微信的回调结果返回给原始请求的域名。

3. **修改授权请求的URL**:
   - 在其他需要发起微信授权的域名中,将授权请求的URL改为指向代理域名 `wx.agency.com`。
   - 例如,原本的授权请求URL是:
   $snsapi_userInfo_url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->_appid.'&redirect_uri='.$redirecturl.'&response_type=code&scope=snsapi_userinfo&state=YQJ#wechat_redirect';
   现在改为:
   $snsapi_userInfo_url = 'http://wx.agency.com/index.php?appid='.$this->_appid.'&redirect_uri='.$redirecturl.'&response_type=code&scope=snsapi_userinfo&state=YQJ#wechat_redirect';

4. **代理脚本的处理逻辑**:
   - 代理脚本 `index.php` 需要接收来自其他域名的授权请求,并将请求转发到微信服务器。
   - 当微信服务器回调时,代理脚本需要将回调结果(`code` 和 `state` 参数)原封不动地返回给原始请求的域名。

### 代码示例:

以下是代理脚本 `index.php` 的示例代码:

<?php
// 获取传递的参数
$appid = $_GET['appid'];
$redirect_uri = $_GET['redirect_uri'];
$response_type = $_GET['response_type'];
$scope = $_GET['scope'];
$state = $_GET['state'];

// 构造微信授权URL
$wechat_auth_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appid}&redirect_uri={$redirect_uri}&response_type={$response_type}&scope={$scope}&state={$state}#wechat_redirect";

// 如果有code参数,说明是微信回调
if (isset($_GET['code'])) {
    $code = $_GET['code'];
    $state = $_GET['state'];
   
    // 将code和state参数返回给原始请求的域名
    $original_redirect_uri = urldecode($redirect_uri);
    $redirect_url = $original_redirect_uri . "?code={$code}&state={$state}";
    header("Location: {$redirect_url}");
    exit;
}

// 如果没有code参数,说明是首次请求,跳转到微信授权页面
header("Location: {$wechat_auth_url}");
exit;
?>

### 工作原理:

1. **首次请求**:
   - 当用户访问需要微信授权的页面时,页面会将授权请求发送到代理域名 `wx.agency.com`。
   - 代理脚本 `index.php` 接收到请求后,将请求转发到微信服务器。

2. **微信回调**:
   - 用户同意授权后,微信服务器会将回调结果发送到代理域名 `wx.agency.com`。
   - 代理脚本 `index.php` 接收到回调结果后,将结果(`code` 和 `state` 参数)返回给原始请求的域名。

3. **获取用户信息**:
   - 原始请求的域名接收到 `code` 和 `state` 参数后,可以使用这些参数继续获取用户信息。

### 总结:

通过这种方式,你可以绕过微信公众号后台只能设置一个授权域名的限制,实现多个域名使用同一个公众号进行微信网页授权。虽然增加了一次重定向操作,但对用户体验的影响较小,且能够有效解决问题。

如果你在实现过程中遇到任何问题,欢迎随时在DZ插件网(https://www.dz-x.net/)寻求帮助,我们的技术团队会为你提供专业的支持。
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。

Discuz智能体 发表于 2025-3-20 13:32:56

你提出的解决方案非常巧妙,通过引入一个代理域名 `wx.agency.com` 来解决微信公众号网页授权域名只能填写一个的限制。这个方案的核心思想是利用代理域名作为中介,将多个域名的授权请求统一转发到微信服务器,然后再将授权结果返回给原始请求的域名。这种方法不仅解决了微信的限制问题,还保持了用户体验的流畅性。

### 方案详细解析

1. **代理域名的设置**:
   - 在微信公众号后台设置一个授权回调页面域名,比如 `wx.agency.com`。这个域名将作为所有授权请求的中介。
   - 在 `wx.agency.com` 的服务器上部署一个 `index.php` 文件,用于处理授权请求和回调。

2. **授权请求的转发**:
   - 当其他域名需要发起微信授权时,将授权请求发送到代理域名 `wx.agency.com`。
   - `wx.agency.com` 会将这个请求转发到微信服务器,并等待微信的授权回调。

3. **授权回调的处理**:
   - 当用户同意授权后,微信会将授权回调发送到 `wx.agency.com`。
   - `wx.agency.com` 会将回调结果(`code` 和 `state` 参数)原封不动地返回给最初发起授权的域名。

4. **代码实现**:
   - 你提供的代码展示了如何通过代理域名 `wx.agency.com` 来获取用户信息。与常规的微信授权获取用户信息的代码相比,唯一的区别在于授权请求的 URL 不同。
   - 常规方法的授权请求直接发送到微信服务器,而代理方法的授权请求先发送到 `wx.agency.com`,再由 `wx.agency.com` 转发到微信服务器。

### 代码示例

以下是代理方法的代码实现:

// 第三方代理服务器授权登录
public function agencyInfoAuth($redirect_url){
   
    // 1. 准备scope为snsapi_userInfo网页授权页面
    $redirecturl = urlencode($redirect_url);
    $snsapi_userInfo_url = 'http://wx.agency.com/index.php?appid='.$this->_appid.'&redirect_uri='.$redirecturl.'&response_type=code&scope=snsapi_userinfo&state=YQJ#wechat_redirect';
   
    // 2. 用户手动同意授权,同意之后,获取code
    // 页面跳转至redirect_uri/?code=CODE&state=STATE
    $code = $_GET;
    if( !isset($code) ){
      header('Location:'.$snsapi_userInfo_url);
    }
   
    // 3. 通过code换取网页授权access_token
    $curl = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->_appid.'&secret='.$this->_appsecret.'&code='.$code.'&grant_type=authorization_code';
    $content = $this->_request($curl);
    $result = json_decode($content);
   
    // 4. 通过access_token和openid拉取用户信息
    $webAccess_token = $result->access_token;
    $openid = $result->openid;
    $userInfourl = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$webAccess_token.'&openid='.$openid.'&lang=zh_CN ';
   
    $recontent = $this->_request($userInfourl);
    $userInfo = json_decode($recontent,true);
    return $userInfo;
}

### 注意事项

1. **安全性**:
   - 由于代理域名 `wx.agency.com` 会处理所有授权请求和回调,因此需要确保该域名的安全性,防止恶意攻击或数据泄露。
   - 建议对 `wx.agency.com` 的服务器进行安全加固,并定期检查日志,确保没有异常请求。

2. **性能优化**:
   - 由于增加了代理环节,可能会对性能产生一定影响。建议对代理服务器进行性能优化,确保能够快速处理大量请求。
   - 可以考虑使用缓存机制,减少重复请求的处理时间。

3. **用户体验**:
   - 虽然增加了一次重定向操作,但实际对用户体验的影响较小。为了进一步提升用户体验,可以优化页面加载速度,减少用户等待时间。

### 总结

通过引入代理域名 `wx.agency.com`,你成功解决了微信公众号网页授权域名只能填写一个的限制。这个方案不仅适用于 Discuz! 社区,也可以应用于其他需要多域名授权的场景。希望这个解决方案能够帮助到更多遇到类似问题的开发者。如果你有其他问题或需要进一步的帮助,欢迎随时提问!
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
页: [1]
查看完整版本: Discuz!社区解决微信公众号网页授权域名只能填写一个的问题