You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Etsy PHP OAuth问题:调用getAccessToken无法获取Access Token

Etsy OAuth 401 Error When Fetching Access Token: Fixes & Debugging

Let's break down why you're hitting that 401 "Invalid auth/bad request" error when calling getAccessToken, and walk through fixing your code step by step.

Common Issues in Your Current Code

First, let's identify the key problems causing the auth failure:

  • Redundant OAuth Instance Creation: Inside getToken, you're re-reading your consumer key/secret and creating a new OAuth instance ($oauth1) instead of reusing the existing one. This is unnecessary and can introduce subtle errors if the key/secret reading fails.
  • Inconsistent Callback URL: Etsy requires the callback URL used in getRequestToken to exactly match the one registered in your Etsy app settings. Your code uses http://localhost/ksec.php—double-check this matches what's in your Etsy app dashboard.
  • Poor Newline Handling: Using trim(fgets($ksecrFile), "\n") doesn't account for Windows-style \r\n newlines, which could leave hidden carriage returns in your consumer key/secret, breaking authentication.
  • Flow Logic Gaps: When handling the callback (after user authorization), you're not properly persisting the request token/secret between the initial redirect and the callback. Right now, you're relying on the $req_token variable from the same request, but that won't exist when Etsy redirects back to your callback URL.

Fixed Code with Explanations

Here's a cleaned-up version of your code that addresses these issues, plus proper credential storage:

<?php
header('Content-type: text/plain');
ini_set('max_execution_time', 600);

// Helper function to read key/secret correctly (handles all newline types)
function readCredentials($filePath) {
    $lines = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    if (count($lines) < 2) {
        die("Invalid credentials file: must contain key on line 1, secret on line 2");
    }
    return [
        'key' => $lines[0],
        'secret' => $lines[1]
    ];
}

// Initialize credentials
$credentials = readCredentials("key_secret.txt");
$consumerKey = $credentials['key'];
$consumerSecret = $credentials['secret'];

// Initialize OAuth client
$oauth = new OAuth($consumerKey, $consumerSecret);
$oauth->disableSSLChecks(); // Only use this for local testing! Remove in production.

// Step 1: Check if we're handling the OAuth callback (have verifier)
if (isset($_GET['oauth_verifier'])) {
    session_start(); // Start session to retrieve stored request token
    // Retrieve the request token/secret we stored in the session
    if (!isset($_SESSION['oauth_request_token'], $_SESSION['oauth_request_token_secret'])) {
        die("Request token not found - please start the auth flow again");
    }

    $requestToken = $_SESSION['oauth_request_token'];
    $requestTokenSecret = $_SESSION['oauth_request_token_secret'];
    $verifier = $_GET['oauth_verifier'];

    // Set the request token before fetching access token
    $oauth->setToken($requestToken, $requestTokenSecret);

    try {
        // Fetch access token
        $accessToken = $oauth->getAccessToken(
            "https://openapi.etsy.com/v2/oauth/access_token",
            null,
            $verifier
        );

        // Success! Store credentials to file first, then database
        $tokenData = implode("\n", [
            $verifier,
            $accessToken['oauth_token'],
            $accessToken['oauth_token_secret']
        ]);
        file_put_contents("token.txt", $tokenData);

        echo "Access token retrieved successfully!\n";
        print_r($accessToken);

        // Now you can insert $accessToken into your database
        // Example: $pdo->execute("INSERT INTO etsy_tokens (token, secret, verifier) VALUES (?, ?, ?)", [$accessToken['oauth_token'], $accessToken['oauth_token_secret'], $verifier]);
    } catch (OAuthException $e) {
        echo "Error fetching access token:\n";
        echo $e->getMessage() . "\n";
        echo "bad";
    }
} 
// Step 2: Check if we already have stored tokens (for testing)
elseif (file_exists("token.txt")) {
    $tokenLines = file("token.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    echo "Stored credentials found:\n";
    echo "Verifier: " . $tokenLines[0] . "\n";
    echo "Access Token: " . $tokenLines[1] . "\n";
    echo "Access Token Secret: " . $tokenLines[2] . "\n";
} 
// Step 3: Start the OAuth flow (no callback, no stored tokens)
else {
    session_start(); // Start session to store request token temporarily

    try {
        // Fetch request token with correct scope and callback
        $requestToken = $oauth->getRequestToken(
            "https://openapi.etsy.com/v2/oauth/request_token?scope=email_r%20listings_r",
            "http://localhost/ksec.php" // Must match Etsy app callback URL exactly
        );

        // Store request token in session for callback use
        $_SESSION['oauth_request_token'] = $requestToken['oauth_token'];
        $_SESSION['oauth_request_token_secret'] = $requestToken['oauth_token_secret'];

        // Redirect user to Etsy authorization page
        $loginUrl = sprintf(
            "%s?oauth_consumer_key=%s&oauth_token=%s",
            $requestToken['login_url'],
            $consumerKey,
            $requestToken['oauth_token']
        );
        header("Location: " . $loginUrl);
        exit;
    } catch (OAuthException $e) {
        echo "Error fetching request token:\n";
        echo $e->getMessage() . "\n";
        die("Failed to start auth flow");
    }
}
?>

Key Fixes Explained

  • Session-Based Request Token Storage: We use PHP sessions to persist the request token/secret between the initial redirect and the callback. This solves the problem of losing the request token data when Etsy redirects back to your app.
  • Proper Credential Reading: The readCredentials function uses FILE_IGNORE_NEW_LINES to automatically strip all newline characters, avoiding hidden whitespace in your key/secret.
  • Simplified OAuth Flow: The code is split into clear steps: handle callback, check for stored tokens, or start the auth flow. No redundant OAuth instances.
  • Callback URL Consistency: Double-check that the callback URL in getRequestToken matches exactly what's set in your Etsy app settings (including http/https, port if needed).

Additional Debugging Tips

  • Enable OAuth Debugging: Add $oauth->enableDebug(); right after initializing the OAuth instance to get detailed logs of the requests/responses, which can help pinpoint auth issues.
  • Check Etsy App Settings: Ensure your consumer key/secret are correct, and the callback URL is an exact match (no trailing slashes, correct protocol).
  • Remove disableSSLChecks() in Production: This is only for local testing—never use it in live environments, as it disables SSL validation.

内容的提问来源于stack exchange,提问作者Pioryby Clowcadia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:40:47