The Community is hosting an End of Summer sweepstakes! Participants must complete tasks to earn tickets that will enter them with a chance to win a free year of Constant Contact and other great prizes!*
*No Purchase Necessary. For Official Rules, visit here. Constant Contact’s End of Summer 2020 Sweepstakes ends on October, 20, 2020 at 11:50 PM EST.

Issue with OAuth2?

Highlighted
Occasional Contributor

Issue with OAuth2?

Here is the pretty straight forward code:

<?php

session_start();

include_once('ctcSupport/ConstantContact.php');

$userName = 'someuser';

$apiKey = 'somekey';

$consumerSecret = 'comesecret';

$accessToken='tokengenerated';

$Datastore = new CTCTDataStore();

 

$sessionConsumer = array(

        'key' => $apiKey,

        'secret' => $consumerSecret,

        'username' => $userName,

    );

$Datastore->addUser($sessionConsumer);

 

$DatastoreUser = $Datastore->lookupUser($userName);

 

if($DatastoreUser){

    $ConstantContact = new ConstantContact('oauth', $apiKey, $DatastoreUser['username'], $consumerSecret);

    $ContactLists = $ConstantContact->getLists();

    if(isset($_POST['emailAddress'])){

        $Contact = new Contact();

        $Contact->emailAddress = $_POST['emailAddress'];

        $Contact->firstName = $_POST['first_name'];

        $Contact->lastName = $_POST['last_name'];

        $Contact->lists = $_POST['contactListName'];

        $NewContact = $ConstantContact->addContact($Contact);

}

}

?>

 

I'm following everything that is mentioned in the wiki, api samples, etc etc, and why still I get 

HTTP Status 401 - Invalid token:$tokenValue

where the $tokenValue is same as the apiKey.

Shouldn't this be the token that is generated once on the fly and then re-used? Where does that token come in to the picture?

 

5 REPLIES 5
Highlighted
Trusted Contributor

Re: Issue with OAuth2?

Hello,

 

This code is using OAuth authentication, With OAuth, if not yet authenticated, you should be redirected to a Constant Contact login page, and after logging in with valid account credentials will be asked to Allow or Deny access for  your application to that account's resources. The remainder of the OAuth flow should return an access token that is different from the API Key, and this access token is what is stored on your server and used to authentication subsequent API Requests. 

 

The error message is telling you your access token is invalid, not your API Key, so you'll need to determine why that's happening. It's not clear from the code you've posted.

Mark Coleman
Support Engineer
Highlighted
Moderator

Re: Issue with OAuth2?

There is a major issue with the way you're using the library that is basically guaranteed to cause a failure to authenticate.  With OAuth 2.0, you need to receive an Access Token that is unique to your API key and the Constant Contact account you're authenticating with.  The library has support for getting this token built in.  In your example, this flow is never being called so I don't see how you would ever be getting an actual Authentication Token for using (and of course storing in the Datastore).

 

Here is the code, taken from our Github Wiki found here, to call OAuth and store it in the DataStore:

 

<?php
include_once('ConstantContact.php'); session_start(); // Session variables must be enabled by default
// Set variables $api_key = 'API KEY'; // API Key $consumer_secret = 'CONSUMER SECRET'; // Consumer Secret $callback_url = 'http://'.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
// Instantiate CTCTOAuth class with credentials $CTCTOAuth = new CTCTOAuth($api_key, $consumer_secret, $callback_url);
if(!$_GET['oauth_verifier']){ //Step 1: Obtain a request token for the new OAuth consumer     $CTCTOAuth->getRequestToken();
    // Store request_token and secret for use after the authorization has been granted     $_SESSION['request_token'] = $CTCTOAuth->request_token->key;     $_SESSION['request_secret'] = $CTCTOAuth->request_token->secret;
//Step 2: Send the user to Constant Contact for authorization     header('Location: '.$CTCTOAuth->generateAuthorizeUrl());
} else { //Step 3: Once authorized, exchange the request token for an access token
    // Create a request_token from the SESSION variables we stored in Step 2     $requestToken = new OAuthToken($_SESSION['request_token'], $_SESSION['request_secret']);     $CTCTOAuth->request_token = $requestToken;
    // Set the authorized username     $CTCTOAuth->username = $_GET['username'];
//Step 4: Request an access token using the 'oauth_verifier' returned from Constant Contact     $CTCTOAuth->getAccessToken($_GET['oauth_verifier']);
    // Create an authorized user and add it to the CTCTDataStore     $sessionConsumer = array(         'key' => $CTCTOAuth->access_token->key,         'secret' => $CTCTOAuth->access_token->secret,         'username' => $CTCTOAuth->username     );
    // Add new user to the datastore     $Datastore = new CTCTDataStore();     $Datastore->addUser($sessionConsumer); } ?>  

Dave Berard
Senior Product Manager, Constant Contact
Highlighted
Occasional Contributor

Re: Issue with OAuth2?

Thanks everyone for the reply.

 

In the first few line, $accessToken=tokengenerated is that token, that I got from the whole page redirect etc etc exercise.

ANyways, I will take a look at the posted code and see whats happening.

 


Highlighted
Occasional Contributor

Re: Issue with OAuth2?

Dave: Thanks for the reply.

Here is the rundown of what I did. I went to the Wiki and looked at the example folder on how to add a contact to the contact list. 

 

Given your reply, does this means the example is inherently wrong? I'm posting here so, that you know and the community can see what I had to begin with:

h2>Add Contact Form Example</h2>
<?php
session_start();
include_once('../ConstantContact.php');
$username = 'USERNAME';
$apiKey = 'APIKEY';
$consumerSecret = 'CONSUMERSECRET';
$Datastore = new CTCTDataStore();
$DatastoreUser = $Datastore->lookupUser($username);
if($DatastoreUser){
    $ConstantContact = new ConstantContact('oauth', $apiKey, $DatastoreUser['username'], $consumerSecret);
    $ContactLists = $ConstantContact->getLists();
?>
<form name="addContact" action="" method="post">
Email Address: <input type="text" name="email_address"><br />
First Name: <input type="text" name="first_name"><br />
Last Name: <input type="text" name="last_name"><br />
<h4>Contact Lists</h4>
<div style="border: 1px #000 solid; overflow: auto; width: 400px; height: 400px;">
<?php
    foreach($ContactLists['lists'] as $list){
        echo '<input type="checkbox" name="lists[]" value="'.$list->id.'"> '.$list->name.'<br />';
    }
    ?>
</div>
<input type="submit" name="submit" value="Add Contact"><br />
</form>
<?php
    if(isset($_POST['email_address'])){
        $Contact = new Contact();
        $Contact->emailAddress = $_POST['email_address'];
        $Contact->firstName = $_POST['first_name'];
        $Contact->lastName = $_POST['last_name'];
        $Contact->lists = $_POST['lists'];
        $NewContact = $ConstantContact->addContact($Contact);
        if($NewContact){
            echo "Contact Added. This is your newly created contact's information<br /><pre>";
            print_r($NewContact);
            echo "</pre>";
        }
    }
} else {echo ' Click <a href="example_verification.php?apiKey='.$apiKey.'&secret='.$consumerSecret.'&return='.$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'].'">here</a> to authorize';}
?>
Secondly, the code snippet given by you, takes me to the CC login page, so does this means every time I'm adding an user, that person will be redirected to the CC login page? I modified the code to 
Is there an interaction diagram/sequence diagram for this whole API workflow. I don't know what other people feel, but this process is a bit low on usability.
Thanks

Highlighted
Moderator

Re: Issue with OAuth2?

The code you have will only prompt an OAuth authenticaion flow (which would bring you to the login screen to grant access to the application for a specific account) if the $Datastore = new CTCTDataStore(); call does not load up your username.  The DataStore in the sample is inheritently incomplete code.  Since we don't know how you store data on your server, we have not coded a permanent storage feature into that piece of the code.  You would need to implement yor server side storage implementation (SQL, NoSQL, text, encrypted text, etc.) that you want to use to store the content and load the stored content for this to work.

Dave Berard
Senior Product Manager, Constant Contact
Developer Portal

View API documentation, code samples, get your API key.

Visit Page

Constant Contact 2020 End of Summer Community Sweepstakes!

The Constant Contact User Community is hosting a sweepstakes. The more you participate, the more chances you have to win! Read on to learn more...

Read More
Featured