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

新浪微博 OAuth 1.0a 授權流程全解析:從請求 Token 到 Access Token 存儲的完整實現

     編輯:PHP 綜合知識

OAuth 1.0a 三步驟流程

  1. 獲取 Request Token:應用向新浪申請臨時憑證。
  2. 用戶授權:用戶在新浪頁面登錄並授權,新浪重定向回應用帶 oauth_verifier。
  3. 換取 Access Token:應用攜帶 Request Token + Verifier 申請長期訪問憑證。

數據庫設計

CREATE TABLE `oauth_users` (
  `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  `oauth_provider` VARCHAR(10) DEFAULT 'sina',
  `oauth_uid` VARCHAR(64) NOT NULL,          -- 新浪用戶數字 ID
  `oauth_token` VARCHAR(255) NOT NULL,       -- Access Token
  `oauth_secret` VARCHAR(255) NOT NULL,      -- Access Token Secret
  `username` VARCHAR(100) DEFAULT '',        -- 昵稱
  UNIQUE KEY `uniq_provider_uid` (`oauth_provider`, `oauth_uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

步驟一:index.php 發起授權

getRequestToken(); // 獲取 oauth_token, oauth_token_secret

$_SESSION['oauth_request_token'] = $requestToken; // 保存供 callback 使用

$authorizeUrl = $oauth->getAuthorizeURL($requestToken['oauth_token'], false, CALLBACK_URL);
?>
使用新浪微博登錄

步驟二:callback.php 處理回調

getAccessToken($_GET['oauth_verifier']); // 關鍵步驟

// 獲取用戶信息
$user = $oauth->get('account/verify_credentials');
if (isset($user->error) || empty($user->id)) {
    header('Location: index.php'); exit;
}

// 數據庫 upsert
$pdo = new PDO(DB_DSN, DB_USER, DB_PASS);
$stmt = $pdo->prepare("SELECT * FROM oauth_users WHERE oauth_provider='sina' AND oauth_uid=?");
$stmt->execute([$user->id]);
$row = $stmt->fetch();

if ($row) {
    $pdo->prepare("UPDATE oauth_users SET oauth_token=?, oauth_secret=? WHERE id=?")
        ->execute([$accessToken['oauth_token'], $accessToken['oauth_token_secret'], $row['id']]);
    $userId = $row['id'];
} else {
    $pdo->prepare("INSERT INTO oauth_users (oauth_provider, oauth_uid, username, oauth_token, oauth_secret)
                   VALUES ('sina', ?, ?, ?, ?)")
        ->execute([$user->id, $user->screen_name, $accessToken['oauth_token'], $accessToken['oauth_token_secret']]);
    $userId = $pdo->lastInsertId();
}

// 寫入 Session 登錄態
$_SESSION['user_id'] = $userId;
$_SESSION['username'] = $user->screen_name;
$_SESSION['oauth_token'] = $accessToken['oauth_token'];
$_SESSION['oauth_secret'] = $accessToken['oauth_token_secret'];

header('Location: update.php'); // 跳轉到發布/主頁
?>

關鍵安全細節

  1. oauth_verifier 單次使用:刷新 callback 頁面會報錯「Token used」,必須重新發起授權流程。
  2. State 參數防 CSRF:
    $authorizeUrl = $oauth->getAuthorizeURL($token, false, CALLBACK_URL, $state);
    Session 存 $state,Callback 驗證 $_GET['state'] === $_SESSION['state']。
  3. HTTPS 強制:生產環境所有 OAuth 交互必須走 HTTPS,防竊聽 Token/Secret。
  4. Token 加密存儲:資料庫中 oauth_token/secret 建議 AES 加密,密鑰配置在環境變量。

update.php 登錄態展示



OAuth 登錄成功

歡迎,

發布微博 | 退出

WeiboOAuth 類核心方法簽名

class WeiboOAuth {
    public function __construct($consumerKey, $consumerSecret,
                                $oauthToken = null, $oauthTokenSecret = null) { ... }
    public function getRequestToken() { ... }           // 返回 ['oauth_token'=>..., 'oauth_token_secret'=>...]
    public function getAuthorizeURL($token, $signInWithSina, $callbackUrl, $state = null) { ... }
    public function getAccessToken($verifier) { ... }    // 返回 ['oauth_token'=>..., 'oauth_token_secret'=>..., 'user_id'=>...]
    public function get($api, $params = []) { ... }      // 簽名 GET 請求
    public function post($api, $params = [], $files = []) { ... } // 簽名 POST 請求
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved