在实际的需求中,我们常常遇到多个部署在不同域名下的业务,想使用同一个「微信服务号」进行微信网页授权。但是微信的网页授权只能设置两个个回调地址。为了满足业务需求,有人想到给每个业务部门配置一个微信服务号,但是这样的成本太高昂。每个服务号需要定期缴纳年检费用,而且每一个网页授权都需要配置相应后端。那么,如何解决 微信网页授权域名只能授权两个 ?
解决办法
制作微信回调中转器,通过授权给中转器实现,多域名分发跳转
中转域名 http://transfer.example.com/ 下的php
<?php
namespace app\index\controller;
use app\BaseController;
use think\facade\View;
use think\facade\Db;
use think\facade\Cache;
class Wechat extends BaseController
{
public $arrayurl=['http://aa.example.com/rep','http://bb.example.com/index/wechat/rep'];
public $arraytype=['infoh5'];
public $APPID = "xxx";
public $SECRET = "xxx";
//授权登录
public function actionScopeRedirectUriAppid(){
$tourl=input('tourl');
if(empty($tourl)||!in_array($tourl,$this->arrayurl)){
exit('非法路径');
}
$type=input('type');
if(empty($type)||!in_array($type,$this->arraytype)){
exit('非法操作');
}
$REDIRECT_URI= 'http://'.$_SERVER['HTTP_HOST'].'/index/wechat/actionWeixinOpenidCallback?tourl='.$tourl.'&&type='.$type;
$scope='snsapi_userinfo'; //手动授权snsapi_userinfo 静默授权snsapi_base
$url='https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->APPID.'&redirect_uri='.urlencode($REDIRECT_URI).'&response_type=code&scope='.$scope.'&state=scene#wechat_redirect';
header("Location:{$url}");
die();
}
##微信回调,获取openid
public function actionWeixinOpenidCallback(){
$tourl=input('tourl');
if(empty($tourl)||!in_array($tourl,$this->arrayurl)){
exit('非法路径');
}
$type=input('type');
if(empty($type)||!in_array($type,$this->arraytype)){
exit('非法操作');
}
if($code= input('code')){
//h5的access_token
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->APPID}&secret={$this->SECRET}&code={$code}&grant_type=authorization_code";
$UserOpenidArr = json_decode($this->dogetCurl($url),1);
if(empty($UserOpenidArr ['openid']) ) {
print_r( $UserOpenidArr );
die("授权失败");
}
$openid=$UserOpenidArr ['openid'];
session('openid',$openid);
\think\facade\Session::save();
session('access_token',$UserOpenidArr['access_token']);
\think\facade\Session::save();
$openid=session('openid');
$access_token=session('access_token');
$token=$this -> getAccessToken();
if($type=="infoh5"){
//跳转h5获取用户信息
header("Location:http://transfer.example.com/index/wechat/actionWeixinOpenidGetUserInfo?openid={$openid}&&access_token={$access_token}&&tourl={$tourl}" );
}
die();
}else{
die("微信授权失败");
}
}
//h5获取用户信息
public function actionWeixinOpenidGetUserInfo(){
$tourl=input('tourl');
if(empty($tourl)||!in_array($tourl,$this->arrayurl)){
exit('非法路径');
}
$openid= input('openid');
$access_token=input('access_token');
$res=$this->getapktj("https://api.weixin.qq.com/sns/userinfo?access_token={$access_token}&openid={$openid}&lang=zh_CN");
$res['nickname']=preg_replace('/[\x{10000}-\x{10FFFF}]/u', '', $res['nickname']);
$res['access_token']=$access_token;
$res['token']=$this ->getAccessToken();
$res=http_build_query($res);
header("Location:{$tourl}?$res");
die();
}
//跨服务器高级用法
public function getapktj($url){
$method ="GET";
$curl = curl_init();
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_FAILONERROR, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
$ret = curl_exec($curl);
$all=json_decode($ret,true);
return $all;
//返回数组
}
public function getAccessToken(){
if(!Cache::get("token")){
//公众号的access_token
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->APPID}&secret={$this->SECRET}";
$UserOpenidArrcgi = json_decode($this->dogetCurl($url),1);
$token=$UserOpenidArrcgi['access_token'];
Cache::set('token',$token,4800);
}
$accessToken = Cache::get("token");
return $accessToken;
}
}
回调目标域名aa.example.com 下的php下的方法
public function checklogin(){
if(!session('openid')||!session('access_token')||!Cache::get("token")){ header("Location:http://rep.zlhdsg.com/index/wechat/actionScopeRedirectUriAppid?tourl=http://sg.zlhdsg.com/index/wechat/rep&&type=infoh5");
die();
}
}
public function rep(){
$res=input("get.");
$id=Db::table("users")->where("openid",$res['openid'])->value("id");
if($id){
$res1=Db::table("users")->where('id',$id)->update(['nickname'=>$res['nickname'],'headimgurl'=>$res['headimgurl'],'updated_at'=>date("Y-m-d H:i:s")]);
}else{
$id=$res1=Db::table("users")->insertGetId(['openid'=>$res['openid'],'nickname'=>$res['nickname'],'headimgurl'=>$res['headimgurl'],'created_at'=>date("Y-m-d H:i:s"),'updated_at'=>date("Y-m-d H:i:s")]);
}
session('openid',$res['openid']);
\think\facade\Session::save();
session('access_token',$res['access_token']);
\think\facade\Session::save();
Cache::set('token',$res['token'],4800);
if($res1){
$this->redirect(url("index/index"));
}else{
echo "error";
}
}
假设中转域名A,授权域名B。B填写在微信公众号网页授权域名栏,A作为跳板?我没看懂。能否详细解释下?