首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 限制頁面僅允許微信內置瀏覽器訪問 (含 User-Agent 偽造防範)

     編輯:PHP 相關知識

營銷活動、企業內部應用常需「僅微信可訪問」。最常見做法是檢測 `User-Agent` 中是否包含 `MicroMessenger`。但 UA 極易偽造 (瀏覽器擴展、代理、curl 均可修改),本文提供**基礎版、進階版、配合 JS/Token 的多層防禦方案**,並說明為何無法 100% 防偽造。

基礎版:單純 UA 判斷

<?php
// 入口文件最頂部
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
if (stripos($userAgent, 'MicroMessenger') === false) {
    // 非微信環境
    header("Content-Type: text/html; charset=UTF-8");
    exit('請在微信客戶端打開此頁面');
}
// 繼續正常業務邏輯
?>

進階版:兼容 Windows Phone 微信 (已停更但存量用戶)

<?php
$userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
$isWechat = stripos($userAgent, 'MicroMessenger') !== false;
$isWPWechat = stripos($userAgent, 'Windows Phone') !== false && stripos($userAgent, 'MicroMessenger') !== false;

if (!$isWechat && !$isWPWechat) {
    exit('非微信環境禁止訪問');
}

偽造演示:為什麼 UA 判斷不可信

<?php
// 任意腳本偽造微信 UA 訪問你的頁面
$ch = curl_init('https://your-domain.com/page.php');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERAGENT => 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.0 NetType/WIFI Language/zh_CN',
    CURLOPT_SSL_VERIFYPEER => false,
]);
$response = curl_exec($ch);
// 返回正常業務內容,防禦失效
curl_close($ch);
?>

Chrome 安裝 User-Agent Switcher 擴展,30 秒即可繞過。

多層防禦方案:提高偽造成本

第 1 層:JS 二次驗證 (阻擋無 JS 環境)

<script>
// 頁面加載時檢測
(function() {
    var ua = navigator.userAgent;
    if (!/MicroMessenger/i.test(ua)) {
        document.body.innerHTML = '
請在微信中打開
'; // 可選:上報偽造嘗試 fetch('/api/log_fake_ua', {method:'POST', body:JSON.stringify({ua:ua})}); } })(); </script> <noscript><style>body{display:none!important}</style><div style="padding:20px;text-align:center;">請啟用 JavaScript 並在微信中打開</div></noscript>

作用:阻擋無頭瀏覽器、curl、簡單爬蟲。但 Headless Chrome/Puppeteer 可執行 JS 繞過。

第 2 層:微信 JSSDK 配置驗證 (強綁定域名、簽名)

<?php
// 後端生成 JSSDK 簽名
$jsApiTicket = get_jsapi_ticket(); // 從 AccessToken 換取,緩存 7200s
$noncestr = 'Wm3WZYTPz0wzccnW';
$timestamp = time();
$url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
$string = "jsapi_ticket=$jsApiTicket&noncestr=$noncestr×tamp=$timestamp&url=$url";
$signature = sha1($string);

// 前端配置
wx.config({
    debug: false,
    appId: 'YOUR_APPID',
    timestamp: $timestamp,
    nonceStr: '$noncestr',
    signature: '$signature',
    jsApiList: ['checkJsApi'] // 僅需驗證配置成功
});

wx.ready(function() {
    // 配置成功 => 確認為合法微信環境 (域名已在公眾平台綁定)
    window.__WX_VERIFIED__ = true;
});
wx.error(function(res) {
    // 配置失敗 => 可能偽造或域名未授權
    document.body.innerHTML = '微信驗證失敗,請在授權域名中打開';
});
?>

原理:JSSDK 簽名包含 `url` 參數,攻擊者無法在非授權域名下構造合法簽名 (除非竊取 `jsapi_ticket`)。

第 3 層:OAuth2.0 靜默授權獲取 OpenID (最強身份驗證)

<?php
// 入口無 code 參數 => 重定向到微信授權
if (!isset($_GET['code'])) {
    $redirect = urlencode('https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
    $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=YOUR_APPID&redirect_uri=$redirect&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
    header("Location: $url");
    exit;
}

// 有 code => 換取 openid
$code = $_GET['code'];
$tokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=YOUR_APPID&secret=YOUR_SECRET&code=$code&grant_type=authorization_code";
$json = file_get_contents($tokenUrl);
$data = json_decode($json, true);
if (empty($data['openid'])) {
    exit('授權失敗');
}
$openid = $data['openid'];
// 此時確認為真實微信用戶,可綁定業務邏輯
$_SESSION['wechat_openid'] = $openid;
?>

優點:無法偽造 (需微信服務器簽發 code)、自動獲取用戶唯一標識。缺點:首次訪問會彈出「正在獲取用戶信息」提示、需公眾號認證、增加一次跳轉延遲。

綜合推薦策略 (按業務敏感度選擇)

場景方案組合偽造成本用戶體驗
普通營銷頁、文章分享UA + JS 檢測低 (繞過簡單)無感
優惠券領取、表單提交UA + JSSDK 配置驗證中 (需竊取 ticket)無感
紅包、支付、個人中心、投票OAuth2.0 靜默授權 (snsapi_base)極高 (需盜用戶手機/微信)首次跳轉 1-2s
高價值交易、實名業務OAuth2.0 用戶信息授權 (snsapi_userinfo) + 後端風控極高需用戶確認授權

總結

  1. **單純 UA 判斷僅能阻擋誤入用戶,不能防禦攻擊者。**
  2. **JSSDK 簽名驗證**是「無感體驗」與「安全性」的最佳平衡點 (需認證服務號)。
  3. **OAuth2.0** 是唯一能確認真實微信用戶身份的方案,核心業務必上。
  4. 所有方案均需**後端 Session/Token 綁定 OpenID**,前端 JS 僅作輔助攔截。
  5. 微信開發者工具、企業微信、小程序 WebView 的 UA 均含 `MicroMessenger`,測試時注意區分。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved