0

我正在尝试编写一个 CodeIgniter 控制器来处理 37signals 的 Basecamp API 的 OAuth2 身份验证。

问题是我在尝试(通过 cURL)连接到https://launchpad.37signals.com/authorization.json时不断遇到“内部校验和失败”错误,在 HTTP 标头中提供 Auth Token。

这是我的控制器类中的 index 和 _authcode 函数:

<?php 

// constants:
// BC_REQUEST_URL = 'https://launchpad.37signals.com/authorization/new'
// BC_TOKEN_URL   = 'https://launchpad.37signals.com/authorization/token'

// ... 

public function index() {
    // if get data is set.
    if ($this->input->get()) {

        // if auth code is provided via GET, switch to _authcode method.
        if ( $code = $this->input->get('code') ) {
            return $this->_authcode($code);
        }

        // On error, kill yourself.
        if ( $error = $this->input->get('error') ) {
            die($error);
        }

    }

    // redirect to 37 signals to get an authcode
    header("Location: ".BC_REQUEST_URL."?type=web_server&client_id=".BC_CLIENT_ID."&redirect_uri=".BC_REDIRECT_URL."");
}

// handles the Authentication code that is returned by 37 Signals.
private function _authcode($code) {
    // set vars to POST
    $vars = array(
        'type' => 'web_server',
        'client_id' => BC_CLIENT_ID,
        'redirect_uri' => BC_REDIRECT_URL,
        'client_secret' => BC_CLIENT_SECRET,
        'code' => $code
    );

    // make a request for the access_token
    $url = BC_TOKEN_URL;
    $c = curl_init($url);
    curl_setopt($c, CURLOPT_POST, true);
    curl_setopt($c, CURLOPT_POSTFIELDS, http_build_query($vars));
    curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
    $response = json_decode(curl_exec($c));
    curl_close($c);
    unset($c,$url);

    // get the access vars from this request
    $expiry_seconds = $response->expires_in;    // default: 1209600 (14 days)
    $refresh_token  = $response->refresh_token; 
    $access_token   = $response->access_token;  
    unset($response);

    // make a separate request to get user info for current user.
    $url = "https://launchpad.37signals.com/authorization.json";
    $c = curl_init($url);

    curl_setopt($c, CURLOPT_HTTPHEADER, array(
        "Authorization: Bearer <$access_token>",
        "Content-Type: application/json; charset=utf-8",
        "User-Agent: MyApp (http://myapp.example.com)"
    ));
    curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
    $response = json_decode(curl_exec($c)); // reply from 37 signal auth
    curl_close($c);
    unset($c,$url);

    echo "response obj = " . print_r($response,1);
    /* prints: response obj = stdClass Object ( [error] => OAuth token could not be verified. The internal checksum failed, so the token data was somehow mangled or tampered with. ) */

    // get the user data from this request
    // $expires_at = $response->expires_at; // the timestamp for when this request expires
    // $identity   = $response->identity;   // the current user
    // $accounts   = $response->accounts;   // list of accounts we can access
    // unset($response);

    // store the response data to the database for easy recall.
    // $this->db->query("REPLACE INTO `sometable` SET `key1`='value', `key2`='value');

}
// ...
?>
4

1 回答 1

1

使用 varchar(255) 将身份验证令牌保存在数据库中时遇到此错误。Basecamp 的身份验证令牌有一些校验和数据,使令牌超过 255 个字符。

在您的示例中,您似乎没有从数据库中提取它,因此这可能不会影响您,但是检查 Basecamp 的令牌是否被切断是我首先要查看的内容。

或者,在设置 Bearer 标头时删除 $access_token 周围的 <> 字符。

于 2012-09-11T17:51:47.873 回答