cancel
Showing results for 
Search instead for 
Did you mean: 

401 Error on generated access_token

SOLVED
Occasional Contributor

401 Error on generated access_token

Hello,

 

I've modified the example from the PHP Wrapper so the tokens are stored in the database.  

(Once we get this working we will have two-way encryption on them to keep em safe).  

I take in the username, apikey, and consumer_secret.  Use the wrapper to generate the request_token and secret in cURL.

 

Our page then redirects to the OAuth login, the user grants access - redirects back to our page with the oauth_token, oauth_verifier and username.

 

When the data comes back i use the oauth_verifier to generate the access_token from the php wrapper (Which uses cURL).

$CTCTOAuth->getAccessToken($_SESSION['oauth_verifier']);
//Unset the oauth_verifier. (Changes api key)
unset($_SESSION['oauth_verifier']);

 

 

These values are then accessable from

$CTCTOAuth->access_token->key          and

$CTCTOAuth->access_token->secret

 

I store these values in a 255 VARCHAR latin1 database.

I now get 401 errors when trying to request or create things.  It could be the database (special characters not in latin1), or me requesting for too many access_tokens, or just something I overlooked

 

HTTP Status 401 - The token 349039bb-f319-4769-ba3c-803509dcfdb1 is not a valid access token.

 

Is that even the right format for an access_token?  (It's not valid anymore I definitely requested several more trying to test authentication).

Or am I storing the wrong value?

 

I can provide more information if needed.

 

Thanks a bunch,

 

Jordan Clark

9 REPLIES 9
CTCT Employee

Re: 401 Error on generated access_token

Hi Jordan,

 

That is indeed the right format for an access token.  They should be in the format 8-4-4-4-12 (where my numerals are the number of characters), just like yours.  We wouldn't be giving you access tokens with any special characters, just a-f, A-F, 0-9 and dashes.

 

Is it possible that you're not matching up usernames to their correct access tokens?  Or perhaps a space is getting inserted into the access tokens?

 

Best Regards,

Shannon W.

API Support Specialist

Occasional Contributor

Re: 401 Error on generated access_token

Hey Shannon,

 

I was storing the username from user input from our site - but I have now reverted to getting the username on the $_GET['username'] parameter.

 

**Edit:  I'll also mention I'm only using one user at this point.  So crossing keys/usernames wouldn't be an issue.

 

I've also checked to see if there were whitespaces, which there were not.

 

I'm still getting invalid token though.  I've made a couple insights on my token value though.

 

1.  The token (not secret) always has lower case letters (just a-f not A-F).  This might be the problem because a!=A.

2.  The secrets have all variations of letters a-f, A-F, 0-9.

 

This is the case not only for the access token/secret, but also the request token/secret.

 

Thanks a bunch,

 

Jordan Clark

 

CTCT Employee

Re: 401 Error on generated access_token

Hi Jordan,

 

Sorry nothing is springing to mind as to what would be the culprit here.  You have successfully used one of your access tokens, and this issue only happens when you try to retrieve them through your database, correct?  Also, my apologies, my access token is also all lowercase, so it is likely that we don't use uppercase for access tokens.

 

Moderator

Re: 401 Error on generated access_token

I looked up that token in our access_token database and do not see any active access_token with that value.  Looks like the error message is valid and what you are passing in is not a valid access_token.  Have you been able to make any successful requests with the access_token values you've retrieved through the OAuth flow? 

Dave Berard
Senior Product Manager, Constant Contact
Occasional Contributor

Re: 401 Error on generated access_token

No I haven't been able to make successful requests.  

Once the authentication was completed (Stored access_token, username), I tried a simple getLists() in the PHP Framework which throws the error.

 

Here is my Authentication code.  Note $this->mData is an array that holds database objects.  it can write / update the database, and has values depending on the array selector.

 

$CTCTOAuth = new \ThirdParty\ConstantContact\CTCTOAuth($this->mData['apiKey'], $this->mData['consumerSecret'], $callback_url);

//If we are getting a new request token (First stage), start here.
if(!isset($_SESSION['oauth_verifier'])){
  //Get the request token
  $CTCTOAuth->getRequestToken();
  if(isset($CTCTOAuth->request_token->key)&&isset($CTCTOAuth->request_token->secret)){
  //Make the 2 request token database objects
  $requestToken = new \BL\ApiKey($this->mBlCore);
  $requestSecret = new \BL\ApiKey($this->mBlCore);
                    
  //Load the requestToken, if it's not there create it.
  $status = $requestToken->Load($this->mId . ',request_token');
  if($status==\BL\Enum\ReturnCode::ERROR_NOOBJECTFOUND){
    $requestToken->AddApiKey($this->mId, "request_token", $CTCTOAuth->request_token->key);
  }else{
    $requestToken->Value = $CTCTOAuth->request_token->key;
  }
  $this->mData['request_token'] = $CTCTOAuth->request_token->key;
  $requestToken->Save();

  //Load the requestSecret, if it's not there create it.
  $status = $requestSecret->Load($this->mId . ',request_secret');
  if($status==\BL\Enum\ReturnCode::ERROR_NOOBJECTFOUND){
    $requestSecret->AddApiKey($this->mId, "request_secret", $CTCTOAuth->request_token->secret);
  }else{
    $requestSecret->Value = $CTCTOAuth->request_token->secret;
  }
  $this->mData['request_secret'] = $CTCTOAuth->request_token->secret;
  $requestSecret->Save();
                    
  //Return the URL - which points to CC login, to grant access to the application.
  return $CTCTOAuth->generateAuthorizeUrl();
}
  else{
    return;
  }
}

//Got the auth_verifier
//Make access_token else{ //username database object $username = new \BL\ApiKey($this->mBlCore); $requestToken = new \ThirdParty\ConstantContact\OAuthToken($this->mData['request_token'], $this->mData['request_secret']); $CTCTOAuth->request_token = $requestToken; $CTCTOAuth->username = $_SESSION['username']; //Load the username, if it's not there create it. $status = $username->Load($this->mId . ',username'); if($status==\BL\Enum\ReturnCode::ERROR_NOOBJECTFOUND){ $username->AddApiKey($this->mId, "username", $CTCTOAuth->username); }else{ $username->Value = $CTCTOAuth->username; } $this->mData['username'] = $CTCTOAuth->username; $username->Save(); $CTCTOAuth->getAccessToken($_SESSION['oauth_verifier']); //Unset the oauth_verifier & username. unset($_SESSION['oauth_verifier']); unset($_SESSION['username']); //Gotta check if it's set if(isset($CTCTOAuth->access_token->key)&&isset($CTCTOAuth->access_token->secret)){ //Load up and put in access_token and access_secret. $accessToken = new \BL\ApiKey($this->mBlCore); $accessSecret = new \BL\ApiKey($this->mBlCore); $status = $accessToken->Load($this->mId . ',access_token'); if($status==\BL\Enum\ReturnCode::ERROR_NOOBJECTFOUND){ $accessToken->AddApiKey($this->mId, "access_token", $CTCTOAuth->access_token->key); }else{ $accessToken->Value = $CTCTOAuth->access_token->key; } $this->mData['access_token'] = $CTCTOAuth->access_token->key; $accessToken->Save(); $status = $accessSecret->Load($this->mId . ',access_secret'); if($status==\BL\Enum\ReturnCode::ERROR_NOOBJECTFOUND){ $accessSecret->AddApiKey($this->mId, "access_secret", $CTCTOAuth->access_token->secret); }else{ $accessSecret->Value = $CTCTOAuth->access_token->secret; } $this->mData['access_secret'] = $CTCTOAuth->access_token->secret; $accessSecret->Save(); //Everythings good. Integrated. return "Constant Contact Integration Successful"; } else{ //Something went wrong. return; } }

 

 

The return is the URL which opens the OAuth login for the user on your site.  When granted back, I have an index which stores the values in Session so I can use them in my integration page.

 

$oauth_verifier = $_GET['oauth_verifier'];
$username = $_GET['username'];
    if($oauth_verifier){
       session_start();
       $_SESSION['oauth_verifier'] = $oauth_verifier;
       $_SESSION['username'] = $username;
       header("Location: settings.php");
    }
    else{
        header("Location: indexOrganization.php");
    }

I'm just using the username and access_token.  

 

 

Storing the key from $CTCTOAuth->access_token->key;

Storing the secret from $CTCTOAuth->access_token->secret;

Storing username from $_GET['username'];

 

 

I use these values to make the request

 

$this->mIntegrationApi = new \ThirdParty\ConstantContact\ConstantContact('oauth2', $this->mData['apiKey'], $this->mData['username'], $this->mData['access_token']);

//Validation Error here
return $this->mIntegrationApi->getLists();

 

Which throws the invalid token error.

 

So what do I have and what am I using?

 

apiKey - inserted by user.

consumerSecret - inserted by user

request_token - Made within the framework and stored in db

request_secret - Made within the framework and stored in db

username - Passed back when authenitcation was granted from OAuth

oauth_verifier - Passed back when the authentication was granted from OAuth

access_token - Made within the framework  from the $requestToken object and the oauth_verifier

access_secret - Made within the framework from the $requestToken object and the oauth_verifier 

 

 

I would think if some parameters were incorrect it wouldn't generate the access_token in the first place (Considering it's being made from cURL).

 

Edit:  Im on a trial account, would that matter?

 

Thanks,

 

Jordan Clark

 

 

 

Moderator

Re: 401 Error on generated access_token

Hi Jordan,

 

I think part of the problem is stemming from your use of OAuth, instead of OAuth2. OAuth is a lot more convoluted and difficult to use, and the smallest error in authentication can cause issues like this. An example verification script for OAuth2 can also be found in the Wrapper's files, and uses far less code.

 

Eventually, we will be deprecating basic and OAuth authentication, so moving into OAuth2 now would probably be the best move here for that reason as well. We can definitely still do some troubleshooting on the code here to see what the problem is if you'd like to stick with OAuth, but the time it's taking us here would likely be better spent in changing over.

Nick Galbraith
Support Engineer
Occasional Contributor

Re: 401 Error on generated access_token

Hey Nick!

 

Thanks for tip, I thought I was using OAuth2, that must be the issue!  I'll fix this up, sorry for blast of code there, I was a bit frustrated.

 

I'll get on this and let you know!

 

Thanks again,

 

Jordan Clark

Highlighted
Moderator

Re: 401 Error on generated access_token

No worries at all, I completely understand coding frustration :)

 

Hope all works out, definitely let us know!

Nick Galbraith
Support Engineer
Occasional Contributor

Re: 401 Error on generated access_token

That was exactly the problem!  I was using OAuth original to create the key / store the key, but using OAuth2 to request things.

 

Here's the (A lot smaller) OAuth2 code, just incase this helps someone out in the future.

 

if(!isset($_SESSION['code'])){
  $url = "https://oauth2.constantcontact.com/oauth2/oauth/siteowner/authorize?response_type=code&client_id="
  . $this->mData['apiKey'] . "&redirect_uri=" 
  . $callback_url;
  return $url;
}else{
  $oAuth2 = new  \ThirdParty\ConstantContact\CTCTOauth2($this->mData['apiKey'], $this->mData['consumerSecret'], $callback_url, $_SESSION["code"]);
  $token = $oAuth2->getAccessToken();
                
  $username = new \BL\ApiKey($this->mBlCore);
  $status = $username->Load($this->mId . ',username');
  if($status==\BL\Enum\ReturnCode::ERROR_NOOBJECTFOUND){
    $username->AddApiKey($this->mId, "username", $_SESSION["username"]);
  }else{
    $username->Value = $_SESSION["username"];
  }
$this->mData['username'] = $_SESSION["username"];
$username->Save();
                
$accessToken = new \BL\ApiKey($this->mBlCore);
$status = $accessToken->Load($this->mId . ',access_token');
if($status==\BL\Enum\ReturnCode::ERROR_NOOBJECTFOUND){
  $accessToken->AddApiKey($this->mId, "access_token", $token);
}else{
  $accessToken->Value = $token;
}
$this->mData['access_token'] = $token;
$accessToken->Save();
                
unset($_SESSION["code"]);
unset($_SESSION["username"]);

return "Constant Contact Integration Successful";

 

Thank you all so much.

 

Jordan Clark