Overview

OAuth2 provides a standard mechanism for allowing users to authorize 3rd Party applications without the need for those applications to request the user's credentials (username/password) or requiring the user to copy & paste API Keys.

Reading standards is no fun, but here are some resources and information that may prove helpful:

  • the current OAuth2 spec.
  • Technically our server implements v10 of the spec. However, the only flow we currently support is the Web Server flow, which has been around for quite some time without much change. In other words pre-v10 and post-v10 clients are likely to work.
  • The wiki previously linked also lists some client libraries you can try out.
  • OAuth2 (on the server side) is pure HTTPS. If you can use HTTPS for your redirect_uri, that would be best, but we don't currently enforce that.
  • Just want to see an actual flow? We have an extremely basic sample app up that you can authorize and de-authorize your account for. That code is also available in a github repo
  • We are not expiring access tokens, thus you will not need a refresh_token.
  • Desktop apps likely will not want to use OAuth2, but could using an in-app browser control. Ditto for native mobile apps (that's what ours do).

Implementation Details

The OAuth2-specific endpoints you'll need to worry about:

  • authorize_uri: https://login.mailchimp.com/oauth2/authorize
  • access_token_uri: https://login.mailchimp.com/oauth2/token
  • redirect_uri: this is on your side. This simply needs to be accessible to the browser being used, obviously
    • Beginning 2013-03-25, wildcard redirect_uris started automatically being supported. This allows, say, a redirect_uri of https://mydomain.com/ to be entered when configuring an app and then passing a redirect_uri of https://user1.mydomain.com/ or https://user2.mydomain.com/ in Step 1 of the authorization process.
    • One caveat - for wildcard support to work, the redirect_uri must appear to be a user-registerable domain under a top level domain. So, for example, if you entered https://co.uk/ as a redirect_uri, wildcard support will not work. However, if you entered https://mydomain.co.uk/ wildcard support will work just fine. These checks are based largely off of the code and data available here.

The MailChimp-specific metadata endpoint you'll need to use:

  • https://login.mailchimp.com/oauth2/metadata
  • - this will provide you with datacenter-specific information about the account so you can make proper API calls.

And now the actual full flow (refer to the urls above):

  1. Your application begins the authorization process by redirecting the user to the authorize_uri
  2. The user will be prompted to enter their username and password to approve your app. Remember Me cookies are not in use here.
  3. Upon successful authentication, we'll redirect the user back to the redirect_uri provided along with a code that you will be able to swap for an access_token. That code will become invalid in 30 seconds (which is PLENTY of time).
  4. Your application must make an out-of-band request to the access_token_uri using the code
  5. We will return an access_token. This completes the official OAuth2 flow, however...
  6. Now you need to make a RESTful request using an OAuth2 client to the metadata url. We will return:
    • dc - datacenter string, ie us1,us2, etc. If you are using a datacenter aware API wrapper, access_token-dc is a standard API Key and can be used as such
    • api_endpoint - this is http://<dc>.api.mailchimp.com. If you don't have a datacenter aware wrapper, use this api endpoint and the access_token as your API Key.
    • login_url - basically, just 'cause someone else has a similar setup and did it too.

Yes, that's right, we are treating the access_token as an API Key. After retrieving that, you won't need to use (and currently can't) an OAuth2 client to make Standard API calls. Users do not have access to these API Keys - they are tied directly to your application. Of course they can later de-authorize your application from inside of MailChimp, at which point the API Key/access_token will be removed and thus become invalid.

Creating Your App

The last step to get your code setup is to create the application your users will authorize. That is done by going to Account -> API Keys & Authorized Apps and clicking through the register/edit your apps button there. Note that users can also de-authorize your app from the Account -> API Keys & Authorized Apps page, so you may as well link that up inside the actual application you are hosting.

Once you've entered the details for your Company and Application and saved them, your client_id and client_secret will be displayed at the bottom of the "edit" page for your application. Pop those into your OAuth2 client and you should be ready to go.

Sample Implementations & Libraries

Full Flow with request/response data

******************************************************************************************
User-specific config:
        - client_id     = 635959587059
        - client_secret = 0da3e7744949e1406b7b250051ee1a95
        - redirect_uri   = http://192.168.1.8/oauth/complete.php

MailChimp Standard OAuth2 config:
        - authorize_uri    =  https://login.mailchimp.com/oauth2/authorize
        - access_token_uri = https://login.mailchimp.com/oauth2/token
        - base_uri         = https://login.mailchimp.com/oauth2/

MailChimp Custom config:
        - metadata_uri     = https://login.mailchimp.com/oauth2/metadata

******************************************************************************************


******************************************************************************************
Step 1: Your application begins the authorization process by redirecting the user to the authorize_uri

        - this is a GET request
        - response_type=code, your client_id, and the *urlencoded* redirect_uri are included
******************************************************************************************

authorize_uri = https://login.mailchimp.com/oauth2/authorize?response_type=code&client_id=635959587059&redirect_uri=http%3A%2F%2F192.168.1.8%2Foauth%2Fcomplete.php

******************************************************************************************
Step 2: The user will be prompted to enter their username and password to approve your app. Remember Me cookies are not in use here.

        - there is nothing to show here. This is the MailChimp login page. We will be redirecting back to your redirect_uri as a GET with the "code" parameter
******************************************************************************************


******************************************************************************************
Step 3: Upon successful authentication, we'll redirect the user back to the redirect_uri provided along with a code that you will be able to swap for an access_token.

        - we've pulled the code out. the full url we redirected the user back to here was:
            - http://192.168.1.8/oauth/complete.php?code=1edf2589e664fd317f6a7ff5f97b42f7
******************************************************************************************

code = 1edf2589e664fd317f6a7ff5f97b42f7


******************************************************************************************
Step 4: Your application must make an out-of-band request to the access_token_uri using the "code" returned

        - This is a POST request
        - as you can see, grant_type, client_id, client_secret, code, and redirect_uri are *all* POSTed
******************************************************************************************

access_token_uri: https://login.mailchimp.com/oauth2/token

REQUEST:

POST /oauth2/token HTTP/1.1
User-Agent: oauth2-draft-v10
Host: login.mailchimp.com
Accept: application/json
Content-Length: 198
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&client_id=635959587059&client_secret=0da3e7744949e1406b7b250051ee1a95&code=1edf2589e664fd317f6a7ff5f97b42f7&redirect_uri=http%3A%2F%2F192.168.1.8%2Foauth%2Fcomplete.php

******************************************************************************************
Step 5: We will return an access_token. This completes the official OAuth2 flow, however...

        - access_token, expires, and scope are all returned. You only care about access_token
        - note this is a json encoded response
******************************************************************************************
RESPONSE :

HTTP/1.1 200 OK
Date: Tue, 16 Aug 2011 15:00:29 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.9
Set-Cookie: PHPSESSID=4e2c17a3d4923c11fe38ac56db7f3aad; expires=Tue, 16-Aug-2011 15:24:29 GMT; path=/; secure; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store
Pragma: no-cache
Set-Cookie: _AVESTA_ENVIRONMENT=jesse; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTR STP IND DEM"
Set-Cookie: PHPSESSDATA=eee0e31f7c0f35621d33611d6b0a545013bfda92%3A1313508269%3AeNoDAAAAAAE%3D; expires=Tue, 16-Aug-2011 15:24:29 GMT; path=/; domain=login.mailchimp.com; secure; httponly
Content-Length: 79
Content-Type: application/json

{"access_token":"5c6ccc561059aa386da9d112215bae55","expires_in":0,"scope":null}


******************************************************************************************
Step 6: Now you need to make a RESTful request using an OAuth2 client to the metadata url.

        - Since no parameters are required, this is essentially an empty GET request
        - The Authorization header is the magic here - that's your access_token
        - Again, json encoded response
******************************************************************************************

REQUEST:

GET /oauth2/metadata HTTP/1.1
User-Agent: oauth2-draft-v10
Host: login.mailchimp.com
Accept: application/json
Authorization: OAuth 5c6ccc561059aa386da9d112215bae55


RESPONSE:

HTTP/1.1 200 OK
Date: Tue, 16 Aug 2011 15:00:29 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.9
Set-Cookie: PHPSESSID=8764d8b5ce6a5279fe0a720e17d0ef54; expires=Tue, 16-Aug-2011 15:24:29 GMT; path=/; secure; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Set-Cookie: _AVESTA_ENVIRONMENT=jesse; path=/
P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTR STP IND DEM"
Set-Cookie: PHPSESSDATA=97598361317a27a35adc55c2d3976e5bdd96d5e9%3A1313508269%3AeNoDAAAAAAE%3D; expires=Tue, 16-Aug-2011 15:24:29 GMT; path=/; domain=login.mailchimp.com; secure; httponly
Content-Length: 105
Content-Type: application/json

{"dc":"us1","login_url":"https:\/\/login.mailchimp.com","api_endpoint":"https:\/\/us1.api.mailchimp.com"}