多网站域名共享微信网页授权:PHP实现微信授权代理转发

在做网站需要微信扫码或微信内授权注册登陆,但是做过类似功能的都知道,需要授权登陆比较麻烦。

需要满足以下条件:

  • 申请公众号
  • 网站域名备案
  • 开放平台注册新建应用审核

有没有简单,不需要申请免备案可用的方案,答案肯定是有,就是利用一个已有备案,已申请好的域名做数据中转,授权转发就行,即微信授权代理。下面就教大家如何实现?建议点赞收藏,如需使用本人搭建的代理,可+薇文章底部扫码+v。

微信网页授权文档:

微信网页授权PC扫码授权和移动端授权是不同的地址不同的接口。

PC扫码授权:

https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

移动端微信内授权:

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

开发指南网页授权流程分为四步:

1.引导用户进入授权页面同意授权,获取code。----- 代理在这一步做。

2.通过code换取网页授权access_token(与基础支持中的access_token不同)

3.如果需要,开发者可以刷新网页授权access_token,避免过期

4.通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

微信网页授权代理转发原理图:

实例教程:

A域名:a.com,无备案使用微信网页授权方法。

在a.com增加一个方法生成代码链接跳转

B域名作为代理:b.com/proxy.php

php 复制代码
function create_proxy()
{
		$device = cmf_is_mobile() ? 'mobile' : 'pc';
        
        $state = time();
        
        $redirect_uri = "http://a.com/proxy_notify";//接受转发回调地址
        $url = "b.com/proxy.php?appid={$config['appid']}&redirect_uri={$redirect_uri}&response_type=code&scope=snsapi_base&state={$state}&device={$device}";
        header("location: {$url}");//跳转到代理链接
}

A域名接受代理转发的数据,

bash 复制代码
function wxlogin()
{
	if (!isset($_GET['code'])) {
            $http_referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : cmf_get_domain();//跳回原页面
            session('http_referer', $http_referer);

            $state = md5(uniqid(rand(), true));
            $callback = urlencode($redirect_uri);
            $wxurl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=$callback&response_type=code&scope=snsapi_userinfo&state=$state#wechat_redirect";
            $this->redirect($wxurl);
        }else{
            //第二步:通过code获取access_token
            $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appid .'&secret=' . $appkey . '&code=' . $_GET['code'] .'&grant_type=authorization_code';
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_URL, $url);
            $json = curl_exec($ch);
            curl_close($ch);
            $arr = json_decode($json, 1);

            if(!empty($arr['errcode']))
            {
                exit($arr['errmsg']);
            }

            $access_token = $arr['access_token'];
            $url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $arr['access_token'] .
                '&openid=' . $arr['openid'] . '&lang=zh_CN';
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_URL, $url);
            $json = curl_exec($ch);
            curl_close($ch);
            $userinfo = json_decode($json, 1);
            $openid = $userinfo['openid'];

            if($openid==""){
                echo "登录失败";
                die();
            }

          	//这里处理微信用户信息

            $http_referer = session('http_referer');
            $this->redirect($http_referer);

        }
}

B网站代理文件proxy.php:此文件主要是把回调地址临时存cookies,等微信授权回调时 ,数据原动的转发回原始站点A。

php 复制代码
<?php
function is_HTTPS()
{
    if (!isset($_SERVER['HTTPS'])) return FALSE;
    if ($_SERVER['HTTPS'] === 1) {  //Apache
        return TRUE;
    } elseif ($_SERVER['HTTPS'] === 'on') { //IIS
        return TRUE;
    } elseif ($_SERVER['SERVER_PORT'] == 443) { //其他
        return TRUE;
    }
    return FALSE;
}
function getDomain()
{
    $server_name = $_SERVER['SERVER_NAME'];
    if (strpos($server_name, 'www.') !== false) {
        return substr($server_name, 4);
    }
    return $server_name;
}
$appid = '';
$scope = 'snsapi_login';
$state = '';
$code = '';
$redirect_uri = '';
$device = '';
$protocol = '';
if (is_HTTPS()) {
    $protocol = 'https';
} else {
    $protocol = 'http';
}
if (isset($_GET['device'])) {
    $device = $_GET['device'];
}
if (isset($_GET['appid'])) {
    $appid = $_GET['appid'];
}
if (isset($_GET['state'])) {
    $state = $_GET['state'];
}
if (isset($_GET['redirect_uri'])) {
    $redirect_uri = $_GET['redirect_uri'];
}
if (isset($_GET['code'])) {
    $code = $_GET['code'];
}
if (isset($_GET['scope'])) {
    $scope = $_GET['scope'];
}
if ($code == 'test') {
    exit;
}
if (empty($code)) {
    $authUrl = '';
    if ($device == 'pc') {
        $authUrl = 'https://open.weixin.qq.com/connect/qrconnect';
    } else {
        $authUrl = 'https://open.weixin.qq.com/connect/oauth2/authorize';
    }
    $options = [
        $authUrl,
        '?appid=' . $appid,
        '&redirect_uri=' . urlencode($protocol . '://' . $_SERVER['HTTP_HOST'] . '/'),
        '&response_type=code',
        '&scope=' . $scope,
        '&state=' . $state,
        '#wechat_redirect'
    ];
    //把redirect_uri先写到cookie
    header(implode('', [
        "Set-Cookie: redirect_uri=",
        urlencode($redirect_uri),
        "; path=/; domain=",
        getDomain(),
        "; expires=" . gmstrftime("%A, %d-%b-%Y %H:%M:%S GMT", time() + 60),
        "; Max-Age=" + 60,
        "; httponly"
    ]));
    header('Location: ' . implode('', $options));
} else {
    if (isset($_COOKIE['redirect_uri'])) {
        $back_url = urldecode($_COOKIE['redirect_uri']);
        header('Location: ' . implode('', [
                $back_url,
                strpos($back_url, '?') ? '&' : '?',
                'code=' . $code,
                '&state=' . $state
            ]));
    }
}
?>
相关推荐
lhbian19 小时前
PHP、C++和C语言对比:哪个更适合你?
android·数据库·spring boot·mysql·kafka
catoop20 小时前
Android 最佳实践、分层架构与全流程解析(2025)
android
ZHANG13HAO21 小时前
Android 13 特权应用(Android Studio 开发)调用 AOSP 隐藏 API 完整教程
android·ide·android studio
田梓燊21 小时前
leetcode 142
android·java·leetcode
angerdream21 小时前
Android手把手编写儿童手机远程监控App之JAVA基础
android
菠萝地亚狂想曲1 天前
Zephyr_01, environment
android·java·javascript
sTone873751 天前
跨端框架通信机制全解析:从 URL Schema 到 JSI 到 Platform Channel
android·前端
sTone873751 天前
Java 注解完全指南:从 "这是什么" 到 "自己写一个"
android·前端
catoop1 天前
Kotlin 协程在 Android 开发中的应用:定义、优势与对比
android·kotlin
撒旦物种1 天前
Android WebView 获取内容高度
android·webview