Our site uses forms to collect emails of interested parties and eventually desires to place them into a CC list.
After creating an approved app with an API Key and Redirect Url, I'm following the OAuth2.0 Server Flow (https://v3.developer.constantcontact.com/api_guide/server_flow.html) I'm curious:
This flow seems to assume our UI will be authenticating, which isn't applicable. Precisely: I'm receiving form UX code from "https://api.cc.email/v3/idfed" instead of something non-interactive. We simply want to deploy this component sometime in the future (perhaps days) on a server and have it insert contacts into a particular CC list.
It seems like CC is missing an example of this. I'm happy to follow the OAuth2 flow, but we won't have a browser/user in this flow in our architecture; it's just our server-side component. We desire to use CC from our own servers via a shared-secret mechanism. Questions:
1: Is there another pre-deployment interactive step I need to get an authorization code?
2: Also, it seems like authorization codes expire. Do we have to constantly refresh authorization with the renewal code, even if our site is not actively collecting emails?
3: Overall, this seems like OAuth2 is not the correct security solution for B2B style API usage here. What is Constant Contact's recommended solution for this architecture?
Digging around after writing the original post, I think I'm piecing it together, but CC isn't very clear on the documentation:
1 - Manually sign into CC with and create an approved application.
2 - Create your server architecture using the V3 API - that allows one to inject an access token into the logic at deploy/startup/run time.
3 - Use something (?) to follow the OAuth2 flow to acquire an authorization code and then access & refresh tokens. Note: The CC API help pages can sign into OAuth2 but do not seem to store the refresh token. (See Local Storage for the v3.developer.constantcontact.com domain in your browser tools).
4 - Create an async mechanism to refresh this token periodically, regardless of usage. This seems to be within 2 hours(?)
Step 3 seem especially problematic: What tool does CC recommend to quickly get a visible access token and refresh token, if it must be manually done?
I understand CC may be stepping up the security by removing fixed keys and using the OAuth2 protocol, but they need to make the expected workflow of how B2B integrations must clearer.
Can someone validate that I have this correct?
Thank you for reaching out to Constant Contact's API Support.
You have the information correct. At this time our oAuth2 flow does require user interaction once to type in the username/password of the Constant Contact account that you are sending your email addresses to, and to click the Allow button. Once this is done you will only be dealing with the Access Token and Refresh Token which does not require user interaction.
The Access Token can expire in one of two ways. It will expire after two hours if it is not being used, or it will expire after 24 hours even if it is being used.
Generally we recommend to use a local database to store your Access Token and Refresh Token so you can access these whenever you need them. Also many of our developers have found using a form of timer to refresh the tokens has been useful instead of waiting for an error code.
An example of the timer would be to set one timer for 24 hours and another timer for two hours. The two hour timer resets every time an API call is made. If either timer reaches its end then your program goes through Step 5 in the oAuth flow which is the step to refresh and get new Access/Refresh Tokens.
There have been several requests for an oAuth flow that does not require any user interaction for server to server applications. This is something we are reviewing, but we have not made any decisions on yet.
Thank you for the considered response. This places a more complicated design burden on B2B applications, which we are evaluating. Since the form-based processing does nothing to actually improve security (it merely adds a more-complicated browser-component requirement), please consider a signed-key exchange mechanism (of the same data) instead, following some like this IETF draft proposal:
which could be used within the Steps 3-4 of your OAuth2 flow
I am also struggling with this, and still not entirely clear. Our website is simply trying to add new contacts to a list using info collected from our own registration form.
You've said that "At this time our oAuth2 flow does require user interaction once to type in the username/password of the Constant Contact account that you are sending your email addresses to, and to click the Allow button."
Can you clarify exactly where/how I would do that?
Regarding refreshing the token, we are not making frequent requests -- our token is likely to need refreshing every time we use it. Is there any reason we shouldn't refresh every time we use the API (except the first), rather than setting up a timer? Assuming not, do we need to bother trying the access token first before refreshing, i.e., is it a problem if we attempt to refresh before the token has expired?
Finally, I add my vote for a B2B flow that does not require manual interaction. To me it seems like the most common of uses, but perhaps I'm missing something -- for example is there a simpler mechanism I failed to notice and should be using instead?
I've noted your interest in the B2B oAuth. This is something we are looking in to.
In regards to how you do the login/allow portion; we generally think that is going to occur when the user of the integration (in this case you are the developer and the user) first installs the integration to their website.
Let's take this scenario. The integration is a sign-up form that is being created for use by anyone (this includes yourself). You've finished development and have made the integration available to users to install on their website. Once the integration is installed the user needs to connect the integration to their Constant Contact account. They are then prompted to enter their un/pw, click allow, and now everything is connected. Now behind the scenes the Access/Refresh Token is renewed automatically as needed using whatever method you decide (timers or refreshing before every call, or waiting for an error response then refreshing).
We understand that many developers are requesting a server to server oAuth, but at this time we do not have an option for that. We are looking in to it, but until then the oAuth was designed around a user providing the un/pw and clicking allow.
Thanks Jimmy. In this case the only website it's going in is our own. We're adding our own website registrant's email as a new Contact in our own Constant Contact account. Our customer should not be required to have a Constant Contact account, and if they did, we wouldn't want access to it.
QUESTION 1: Our requirements are so simple that I keep thinking there must be a simpler solution that I've overlooked. Is there?
Meanwhile, I've got this working by manually entering this URL in my browser...
...which redirects to my redirect_uri, with the authorization code as a parameter in the URL. I manually store that as a setting on our site, though it only gets used once. Then I very quickly (because the code expires in 1 minute?) manually create a dummy registration on our site. The code I wrote then looks for a saved access token, and if it doesn't find one, it uses the authorization code to programmatically retrieve and save new access/refresh tokens.
Somewhere in that process -- maybe when the authorization code is used to get the tokens, can't remember -- I'm prompted to manually approve access (for writing Contact data) to our own Constant Contact account. That doesn't seem to happen consistently, i.e., after doing it the first time, I've run through the whole sequence numerous times, and only occasionally have I been prompted. Presumably the approval is cached somewhere for a period of time.
Once the first access/refresh tokens have been saved, whenever someone new registers on our site, my code refreshes/saves the token (every time), then uses it to add the registrant's email as a new Contact in our Constant Contact account.
Assuming there isn't an easier way to do this...I just want to be sure that neither manual step (getting the authorization code, nor approving account access) will ever need to happen again. I think it may if I make changes relating to the api key, e.g., generate a new secret key, or maybe if I change the redirect URI, which we can live with.
QUESTION 2: Are there any other situations at all that would require me to get a new authorization code, or to manually re-approve access to our own account?
Just started evaluating CC and it seems odd that there is no B2B OAuth. Do you have any feedback on if and when this flow will be available.
The process you described under question 1 is what I use when I'm testing with POSTman. I manually put together that URL you wrote out, paste it in to my browser, and get back the authorization code. Then you have 60 seconds to use that code to generate your Access/Refresh Token. Once you have the Access/Refresh Token you should not ever have to go through the process to get an authorization code again.
As for your second question; you should only be prompted to click the Allow/Deny button once. If it ever comes up again it should be due to generating a new Secret, using a new Constant Contact account, or using a new API Key. Assuming you continue to use the same pieces of information that step should not repeat.