Search code examples
phpoauth-2.0authorizationhttp-status-code-400etsy

OAuth PKCE code verifier is invalid 400 HTTP error


I have a problem with OAuth authorization. I keep getting 400string(73) "{"error":"invalid_grant","error_description":"code_verifier is invalid"} " error.

My function to generate code verifier and code challenge:

function GetOauthUrl(){
    $_SESSION["etsy_state"] = getRadomString(128);
    $txt = "";
    for ($i=0; $i < 32; $i++) {
        $txt .= chr(rand(0, 255));
    }    
    $txtEnc = base64_encode($txt);
    $code_challenge = str_replace('=', '', $txtEnc);
    $code_challenge = str_replace('+', '-', $code_challenge);
    $code_challenge = str_replace('/', '_', $code_challenge);

    $hashTxt = base64_encode(hash('sha256',$code_challenge));
    $hash = str_replace('=', '', $hashTxt);
    $hash = str_replace('+', '-', $hash);
    $hash = str_replace('/', '_', $hash);

    $url = "https://www.etsy.com/oauth/connect?response_type=code&client_id={$_SESSION['etsy_clientId']}&redirect_uri=$_SESSION['etsy_url']"
        ."&scope=listings_r%20listings_w%20listings_d&state={$_SESSION['etsy_state']}&code_challenge={$hash}&code_challenge_method=S256";

    $_SESSION["etsy_code_challenge"] = $code_challenge;
    return $url;
}

After retrieve auth code from API, I use function:

function GetOauthToken(){
    $postfields = "grant_type=authorization_code&client_id=".$_SESSION["etsy_clientId"]
        ."&redirect_uri=".$_SESSION['etsy_url']
        ."&code=".$_SESSION["etsy_authCode"]
        ."&code_verifier=".$_SESSION["etsy_code_challenge"];

    $url = "/v3/public/oauth/token";

    return PostHttpRequest($url, array('Cache-Control: no-cache'), $postfields);
}

Please help me.

I want to authorize by OAuth 2.0 in API, but I keep getting error:

400string(73) "{"error":"invalid_grant","error_description":"code_verifier is invalid"} "

Solution

  • Figured it out, I think, by following the example given under https://datatracker.ietf.org/doc/html/rfc7636#appendix-B - you need to base64-encode the raw binary output of the SHA-256 hash, not the lowercase hex-digit version.

    $hashTxt = base64_encode(hash('sha256',$code_challenge,true));
                                                           ^^^^