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

PHP 實現 PayPal 授權登錄(OAuth2/OpenID Connect)完整類封裝

     編輯:PHP 相關知識

PHP 實現 PayPal 授權登錄(OAuth2/OpenID Connect)完整類封裝

封裝 PayPal Login(OAuth2 Authorization Code Flow + OpenID Connect UserInfo)完整流程:構建授權 URL、換取 Access Token、獲取用戶資料。支持沙箱/正式環境切換、自定義 Scope/State/Nonce、CSRF 防護。

類核心代碼

<?php
class paypallogin {
    // 沙箱/正式環境端點
    private $_sanbox_oauth2_auth_uri     = 'https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize';
    private $_live_oauth2_auth_uri       = 'https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/authorize';
    private $_acquire_user_profile_sandbox_url = 'https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/userinfo?schema=openid&access_token=';
    private $_acquire_user_profile_live_url    = 'https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/userinfo?schema=openid&access_token=';
    private $_token_service_sandbox_url = 'https://www.sandbox.paypal.com/webapps/auth/protocol/openidconnect/v1/tokenservice';
    private $_token_service_live_url    = 'https://www.paypal.com/webapps/auth/protocol/openidconnect/v1/tokenservice';

    private $_sanbox_flag = true;
    private $_client_id = null;
    private $_client_secret = null;
    private $_redirect_uri = null;
    private $_state = '';
    private $_scope = 'openid email phone profile address https://uri.paypal.com/services/paypalattributes';
    public $token = null;
    public $protocol = "http";

    public function __construct($redirect_uri, $client_id, $client_secret, $scope, $state, $flag = true) {
        $this->_sanbox_flag  = $flag;
        $this->_redirect_uri = $redirect_uri;
        $this->_client_id    = $client_id;
        $this->_client_secret= $client_secret;
        $this->_scope        = $scope;
        $this->_state        = $state;
    }

    /** 生成授權頁面 URL */
    public function create_request_url() {
        $auth_uri = $this->_sanbox_flag ? $this->_sanbox_oauth2_auth_uri : $this->_live_oauth2_auth_uri;
        $params = array(
            'client_id'     => $this->_client_id,
            'response_type' => 'code',
            'scope'         => $this->_scope,
            'redirect_uri'  => urlencode($this->_redirect_uri),
            'nonce'         => time() . rand(),
            'state'         => $this->_state,
        );
        return $auth_uri . '?' . http_build_query($params);
    }

    /** 用授權碼換取 Access Token */
    public function acquire_access_token($code) {
        $postvals = sprintf(
            "client_id=%s&client_secret=%s&grant_type=authorization_code&code=%s",
            $this->_client_id, $this->_client_secret, $code
        );
        $url = $this->_sanbox_flag ? $this->_token_service_sandbox_url : $this->_token_service_live_url;
        $ch = curl_init($url);
        $options = array(
            CURLOPT_POST           => 1,
            CURLOPT_VERBOSE        => 1,
            CURLOPT_POSTFIELDS     => $postvals,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_SSL_VERIFYPEER => false,
        );
        curl_setopt_array($ch, $options);
        $response = curl_exec($ch);
        curl_close($ch);
        if (!$response) throw new Exception("Error retrieving access token: " . curl_error($ch));
        $json = json_decode($response);
        if (isset($json->access_token)) return $json->access_token;
        throw new Exception("No access_token in response");
    }

    /** 獲取用戶資料 */
    public function acquire_paypal_user_profile($accessToken) {
        $url = ($this->_sanbox_flag ? $this->_acquire_user_profile_sandbox_url : $this->_acquire_user_profile_live_url) . $accessToken;
        $ch = curl_init($url);
        $options = array(
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_SSL_VERIFYPEER => false,
        );
        curl_setopt_array($ch, $options);
        $response = curl_exec($ch);
        curl_close($ch);
        if (!$response) return false;
        return json_decode($response);
    }
}

使用流程

  1. 實例化:$pp = new paypallogin($redirect_uri, $client_id, $client_secret, $scope, $state, $sandbox);
  2. 重定向至授權頁:header('Location: ' . $pp->create_request_url());
  3. 用戶授權後 PayPal 重定向回 $redirect_uri?code=xxx&state=yyy。
  4. 驗證 state 防 CSRF,調用 $token = $pp->acquire_access_token($_GET['code']);。
  5. 獲取用戶信息:$profile = $pp->acquire_paypal_user_profile($token);,解析 $profile->user_id、$profile->email 等。
  6. 綁定/登錄本地用戶,建立會話。

關鍵參數說明

參數說明
response_type=code授權碼模式,安全性高,Token 不暴露於前端
scope權限範圍,openid 必填,其他按需:email、phone、profile、address、paypalattributes
nonce防重放攻擊隨機值,建議 timestamp + base64(random)
stateCSRF 防護,回調時驗證與發起時一致

安全與合規建議

  • **強制 HTTPS**:生產環境 redirect_uri 必須 HTTPS,PayPal 審核要求。
  • CURLOPT_SSL_VERIFYPEER => false 僅測試用,**生產必須開啟驗證**並配置 CA 憑證。
  • 妥善保管 client_secret,不得前端暴露、不入代碼倉庫(用環境變量/密鑰管理)。
  • Token 存儲加密,定期刷新(Refresh Token 流程)。
  • 遵循 PayPal Brand Guidelines 顯示「使用 PayPal 登錄」按鈕。

此類為 OAuth2 Authorization Code + OpenID Connect 標準實現,可作為 PayPal 登錄集成的參考基礎,按項目架構調整異步處理、錯誤重試、日誌審計等工程化細節。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved