新浪微博開放平台採用 OAuth 2.0 授權碼模式。本文從申請應用、配置回調、獲取 Authorization Code、換取 Access Token、獲取用戶資料、錯誤處理、Token 刷新與儲存,提供完整 PHP 實作範例,基於官方 PHP SDK (saetv2.ex.class.php) 並補充現代最佳實踐。
saetv2.ex.class.php。<?php
return [
'weibo' => [
'client_id' => 'YOUR_APP_KEY',
'client_secret' => 'YOUR_APP_SECRET',
'redirect_uri' => 'https://yourdomain.com/callback.php', // 必須與後台一致
'scope' => 'all', // 或指定 scope: 'statuses_to_me_read,users_show_read'
],
];
?>
<?php
require_once 'vendor/autoload.php'; // Composer 載入 easywechat/weibo
$config = require 'config.php';
$app = \EasyWeChat\Weibo\Application::create($config['weibo']);
$oauth = $app->oauth;
// 生成授權 URL (state 參數防 CSRF)
$state = bin2hex(random_bytes(16));
$_SESSION['weibo_oauth_state'] = $state;
$authUrl = $oauth->getAuthorizationUrl($state);
// 產生類似:https://api.weibo.com/oauth2/authorize?client_id=...&redirect_uri=...&response_type=code&state=...
echo "微博登入";
?>
<?php
session_start();
require_once 'vendor/autoload.php';
$config = require 'config.php';
$app = \EasyWeChat\Weibo\Application::create($config['weibo']);
$oauth = $app->oauth;
// 1. 驗證 state 防 CSRF
if (empty($_GET['state']) || $_GET['state'] !== ($_SESSION['weibo_oauth_state'] ?? '')) {
die('非法請求:State 不符合');
}
unset($_SESSION['weibo_oauth_state']);
// 2. 獲取授權碼
$code = $_GET['code'] ?? '';
if (empty($code)) {
die('授權失敗:' . ($_GET['error_description'] ?? '用戶拒絕授權'));
}
try {
// 3. 換取 Access Token
$token = $oauth->getAccessToken($code);
/*
$token 結構:
[
'access_token' => '2.00xxx',
'expires_in' => 157679999, // 秒
'remind_in' => 157679999,
'uid' => '1234567890', // 用戶 UID
'isRealName' => 'true',
]
*/
// 4. 儲存 Token (資料庫/Redis/Session)
// 建議儲存:uid, access_token, expires_at (time()+expires_in), refresh_token (若有)
$_SESSION['weibo_user'] = [
'uid' => $token['uid'],
'access_token' => $token['access_token'],
'expires_at' => time() + (int)$token['expires_in'],
];
// 5. 導向會員中心或首頁
header('Location: /member.php');
exit;
} catch (\EasyWeChat\Kernel\Exceptions\InvalidArgumentException $e) {
die('參數錯誤:' . $e->getMessage());
} catch (\EasyWeChat\Kernel\Exceptions\RuntimeException $e) {
die('網路/服務器錯誤:' . $e->getMessage());
}
?>
<?php
session_start();
require_once 'vendor/autoload.php';
$config = require 'config.php';
if (empty($_SESSION['weibo_user'])) {
header('Location: login.php');
exit;
}
$user = $_SESSION['weibo_user'];
// 檢查 Token 是否過期,需刷新
if ($user['expires_at'] < time()) {
$app = \EasyWeChat\Weibo\Application::create($config['weibo']);
$oauth = $app->oauth;
// 微博不支援標準 Refresh Token,需引導用戶重新授權
// 或使用官方提供的「延長有效期」API (需高級權限)
header('Location: login.php');
exit;
}
$app = \EasyWeChat\Weibo\Application::create($config['weibo']);
$app->setAccessToken($user['access_token']);
// 獲取用戶詳細資料
try {
$profile = $app->user->show($user['uid']);
/*
$profile 結構:
{
"id": 1234567890,
"screen_name": "用戶昵稱",
"profile_image_url": "https://.../avatar.png",
"gender": "m",
"location": "北京 海淀區",
"followers_count": 100,
"friends_count": 50,
"statuses_count": 200,
"verified": true,
"verified_type": 0,
...
}
*/
} catch (\Exception $e) {
die('獲取用戶資料失敗:' . $e->getMessage());
}
?>
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>會員中心</title></head><body>
<h1>歡迎,= htmlspecialchars($profile['screen_name']) ?></h1>
<img src="= htmlspecialchars($profile['profile_image_url']) ?>" alt="頭像">
<p>UID: = $profile['id'] ?></p>
<p>粉絲: = $profile['followers_count'] ?> | 關注: = $profile['friends_count'] ?> | 微博: = $profile['statuses_count'] ?></p>
<a href="logout.php">登出</a>
</body></html>
<?php
session_start();
session_destroy();
header('Location: /');
exit;
?>
| 場景 | 處理方式 |
|---|---|
| Access Token 過期 | 微博不提供標準 Refresh Token。需引導用戶重新授權,或申請「高級權限」使用 oauth2/authorize 靜默續期 (用戶已授權且未撤銷)。 |
| 多伺服器部署 | Token 儲存於 Redis (共享) 或資料庫,Session 僅存 UID。 |
| 安全性 | Access Token 視同密碼,資料庫加密儲存 (AES-256),傳輸全程 HTTPS。 |
| 撤銷授權檢測 | 定時任務嘗試呼叫 users/show,若回傳 error_code=21327 (用戶撤銷授權) 則清除本地 Token。 |
| error_code | 含義 | 處理 |
|---|---|---|
| 21301 | Access Token 過期 | 重新授權 |
| 21302 | Access Token 非法 | 檢查 App Secret、重新授權 |
| 21327 | 用戶撤銷授權 | 清除本地綁定、引導重新登入 |
| 10004 | App Key 不存在 | 檢查 config.php |
| 21321 | 回調頁域名不匹配 | 後台設定與代碼 redirect_uri 嚴格一致 |
easywechat/weibo 積極維護、支援 Laravel/Lumen/原生 PHP、單元測試覆蓋、文件完善。微博 OAuth2 登入核心流程:引導授權 → 回調換碼 → 儲存 Token → 獲取用戶資料。關鍵在於:State 參數防 CSRF、HTTPS 回調域名備案、Token 安全儲存與過期處理、使用現代 SDK (easywechat/weibo)。掌握此流程,即可快速接入微博開放平台的社交登入、分享、評論等能力。