We all started somewhere! Share your experience on the Get Advice: Let's Get Started Sweepstakes thread and be entered to win a $100 credit on your Constant Contact account.

Issue with OAuth2?

ChezR
Regular Participant

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
Mark-C
Member

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
DaveBerard
Moderator

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
ChezR
Regular Participant

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.

 


ChezR
Regular Participant

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

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