接入新浪微博開放平台,核心是 OAuth 2.0 授權碼模式。本文基於官方 PHP SDK,梳理完整授權流程、常見坑點、Token 管理最佳實踐,並提供可直接落地的代碼結構。
App Key (WB_AKEY) 與 App Secret (WB_SKEY)https://yourdomain.com/callback.php(需與代碼一致)composer require weibo/oauth2 或手動引入
用戶點擊「微博登入」
│
▼
導向微博授權頁
https://api.weibo.com/oauth2/authorize?
client_id=WB_AKEY
&redirect_uri=YOUR_CALLBACK
&response_type=code
&scope=all
│
▼
用戶授權(登入+確認)
│
▼
微博重導向回你的 callback.php
https://yourdomain.com/callback.php?code=AUTH_CODE
│
▼
後端用 code 換取 Access Token
POST https://api.weibo.com/oauth2/access_token
client_id, client_secret, grant_type=authorization_code, code, redirect_uri
│
▼
獲得 Access Token + Expires_in + UID
│
▼
儲存 Token,調用 API
config/weibo.php<?php
return [
'app_key' => env('WEIBO_APP_KEY'),
'app_secret' => env('WEIBO_APP_SECRET'),
'redirect_uri' => env('WEIBO_REDIRECT_URI'),
'scope' => 'all', // 或具體權限:'statuses_to_me_read,friendships_groups_read'
];
login.php<?php
require 'vendor/autoload.php';
use Weibo\OAuth2;
session_start();
$config = require 'config/weibo.php';
$oauth = new OAuth2($config['app_key'], $config['app_secret']);
// 生成授權 URL
$authorizeUrl = $oauth->getAuthorizeURL($config['redirect_uri'], $config['scope']);
// 關鍵:儲存 state 防 CSRF(SDK 內部已處理,若手動構建需自行實現)
$_SESSION['weibo_oauth_state'] = bin2hex(random_bytes(16));
header("Location: {$authorizeUrl}");
exit;
callback.php<?php
require 'vendor/autoload.php';
use Weibo\OAuth2;
use Weibo\Client;
session_start();
$config = require 'config/weibo.php';
$code = $_GET['code'] ?? '';
$state = $_GET['state'] ?? '';
if (!$code) {
die('授權失敗:缺少 code 參數');
}
// 可選:驗證 state 防 CSRF
// if ($state !== ($_SESSION['weibo_oauth_state'] ?? '')) { die('State mismatch'); }
$oauth = new OAuth2($config['app_key'], $config['app_secret']);
try {
// 用 code 換取 Access Token
$token = $oauth->getAccessToken('authorization_code', [
'code' => $code,
'redirect_uri' => $config['redirect_uri'],
]);
// $token 結構:['access_token' => '...', 'expires_in' => 3600, 'uid' => '123456', 'remind_in' => ...]
// 關鍵:持久化 Token(關聯你的用戶表)
$pdo = getPdo(); // 你的資料庫連線
$stmt = $pdo->prepare("
INSERT INTO weibo_tokens (uid, access_token, expires_in, created_at)
VALUES (?, ?, ?, NOW())
ON DUPLICATE KEY UPDATE
access_token = VALUES(access_token),
expires_in = VALUES(expires_in),
updated_at = NOW()
");
$stmt->execute([
$token['uid'],
$token['access_token'],
$token['expires_in'],
]);
// 登入你的系統(建立 Session / JWT)
$_SESSION['weibo_uid'] = $token['uid'];
$_SESSION['weibo_token'] = $token['access_token'];
header('Location: /dashboard.php'); // 跳轉應用首頁
exit;
} catch (Exception $e) {
error_log("Weibo OAuth error: " . $e->getMessage());
die('授權處理失敗,請稍後重試');
}
<?php
require 'vendor/autoload.php';
use Weibo\Client;
session_start();
$config = require 'config/weibo.php';
$accessToken = $_SESSION['weibo_token'] ?? '';
if (!$accessToken) {
header('Location: /login.php');
exit;
}
$client = new Client($config['app_key'], $config['app_secret'], $accessToken);
try {
// 獲取最新 20 條公開微博
$response = $client->get('statuses/public_timeline.json', ['count' => 20]);
// SDK 通常已 json_decode,直接回傳陣列
if (isset($response['error_code'])) {
// Token 可能過期,需刷新或重新授權
if ($response['error_code'] == 21327) { // Expired token
// 觸發刷新流程...
}
throw new Exception($response['error']);
}
// 渲染模板
foreach ($response['statuses'] as $status) {
echo "";
echo "{$status['text']}
";
echo "@{ $status['user']['screen_name'] } · {$status['created_at']}";
echo "";
}
} catch (Exception $e) {
error_log("Weibo API error: " . $e->getMessage());
echo "獲取微博失敗";
}
| 場景 | 策略 |
|---|---|
| Access Token 過期 | 微博 Access Token 有效期 30 天,無 Refresh Token 機制。需引導用戶重新授權,或在過期前主動檢查並提醒用戶續授權 |
| 多伺服器部署 | Token 存資料庫(Redis/MySQL),非 Session 檔案,確保多機共享 |
| Token 洩露風險 | 資料庫加密存儲 access_token;日誌脫敏;定期輪換 App Secret |
| 並發請求 | 同一用戶並發調用 API 時,避免重複刷新 Token,用分佈式鎖或「雙檢查」模式 |
| 權限變更 | 用戶在微博端撤銷授權 → API 返回 21327/21332,需清除本地 Token 並引導重新授權 |
21327 : Access token expired
21332 : Invalid / revoked token
21301 : Parameter error (缺少必要參數)
21302 : Redirect uri mismatch
403 : Permission denied (權限不足,檢查 scope)
400 : Bad request (參數格式錯誤)
429 : Rate limited (觸發頻率限制,需指數退避重試)
state 參數防禦 CSRFredirect_uri 嚴格驗證,防開放重導向OAuth 流程看似標準,細節決定成敗。建立標準化接入模板,新專案複製微調,才能高效交付。