OpenPass API authorization code flow
TIP: The Trade Desk recommends using an SDK because it is the easiest option. It can do a lot of the work for you, such as managing security features and returning the user's ID token and access token. If you want to manually implement code for various functions using our API endpoints, use this guide.
This page includes information to help you get up and running with the OpenPass API using the redirect flow for web apps.
NOTE: For apps built for smart TVs and similar devices, use the device grant flow so that the user can enter the authentication code on a separate device.
Setup and requirements
Before implementing the authentication flow, be sure to register the client application with OpenPass. See the following for more information.
API version
The current version of the OpenPass API is v1.
Open API spec
Download the OpenAPI specification using the following endpoint: GET /.well-known/jwks.
OpenPass open ID connect URLs
The following table lists the OpenPass OIDC URLs.
| Endpoints | URL |
|---|---|
| GET /v1/api/authorize | https://auth.myopenpass.com/v1/api/authorize |
| POST /v1/api/token | http://auth.myopenpass.com/v1/api/token |
Implement the OpenPass API
IMPORTANT: Be sure to provide a list of redirect URIs when setting up your account. This is required for the flow to work properly.
If you choose to implement OpenPass using the API instead of an SDK, you'll need to implement code to complete the various functions using the OpenPass API endpoints.
The following are high-level steps for implementing OpenPass using the API:
- Prepare security parameters
- Generate and navigate to the authorize URL
- Exchange authorization code for tokens
Prepare security parameters
As part of the user authentication process, OpenPass supports PKCE as an optional security feature. If PKCE is enabled, OpenPass supports the additional parameters in the following table.
| PKCE Parameter | Description | Sample Value |
|---|---|---|
code_verifier |
A high-entropy cryptographic random string with a minimum length of 43 characters. For details, see POST /v1/api/token. |
762ac555-cabc-452b-972d-4aaaba9cfb2f |
code_challenge |
A Base64 URL-encoded SHA256 hash of the code_verifier value or, if the client is unable to support this, just the code_verifier value, unmodified. For details, see GET /v1/api/authorize. |
1c1d219f-1610-4174-8d24-d75c5cce875a |
code_challenge_method |
Either the S256 value if the code_challenge was created by SHA256 hashing of the code_verifier; or plain if using the code_verifier value unmodified.For details, see GET /v1/api/authorize. |
S256 |
The code challenge is sent in the GET /v1/api/authorize request, and OpenPass stores this value. Later on, the code verifier is sent to the POST /v1/api/token endpoint along with the authorization code in the code property. OpenPass validates the code verifier against the code_challenge value that it previously stored.
This sequence makes sure that the original GET /v1/api/authorize request was sent by the same actor as the POST /v1/api/token request, and prevents cross-site request forgery (CSRF) and authorization code injection attacks.
You can generate the PKCE parameters by using the following pseudo-code as a guideline:
code_verifier = randomString(length=43)
code_challenge = base64UrlEncode(sha256(toAscii(code_verifier)))
code_challenge_method = "S256"
Generate and navigate to the authorize URL
If you're using the redirect flow, the client initiates the authentication flow by directing the user to the authorize URL on a browser with a full-page redirect. A common approach is to generate the authorize URL and link an OpenPass-branded Sign In with OpenPass button to it.
You must generate and store the state parameter, and the optional PKCE security parameters if PKCE is enabled, because they are required later when exchanging the authorization code for the OpenPass tokens. There are multiple ways of doing this. Two examples are:
- Storing them in local storage on the client side.
- Storing them in your user's session storage on the server side.
The authorize base URL is https://auth.myopenpass.com/v1/api/authorize
The following table summarizes the query string parameters. For details, see GET v1/api/authorize.
| Parameter | Additional Information |
|---|---|
client_id |
The unique ID provided to you by The Trade Desk for your client. If you don't have a client_id value, ask your contact at The Trade Desk. |
redirect_uri |
The URI that OpenPass redirects back to after user sign-in or an error during the sign-in. This URI must match the one set up in your client configuration with no fragments. See Account setup in the Getting Started guide. |
response_type |
A parameter required by OpenID Connect. For OpenPass, the value must be code. |
scope |
A parameter required by OpenID Connect. For OpenPass, the value must be openid. |
state |
Another security parameter to help prevent forgery attacks. Often, the state parameter is a random string with sufficient length and entropy. |
code_challenge |
See Prepare security parameters. |
code_challenge_method |
See Prepare security parameters. |
Example code
The following example is pseudo-code to demonstrate an implementation approach for generating and navigating to the URL. This example includes the Java pseudo-code, corresponding HTML coding, and implements it in the backend.
String generateAuthorizeUrl(String userSessionId) {
var clientId = "123abc";
var redirectUri = urlEncode("https://yoursite.com/handle_op_callback");
var state = generateRandomString(50);
var codeVerifier = generateRandomString(50);
var codeChallenge = base64UrlEncode(sha256Hash(codeVerifier);
var codeChallengeMethod = "S256";
this.securityParameterStorage.store(userSessionId, codeVerifier, state);
var authorizeUrlTemplate = "https://auth.myopenpass.com/v1/api/authorize?response_type=code&scope=openid&client_id=%s&redirect_uri=%s&state=%s&code_challenge_method=%s&code_challenge=%s";
return String.format(authorizeUrlTemplate, clientId, redirectUri, state, codeChallengeMethod, codeChallenge);
}
The following HTML implements the example in the user interface, providing the Sign In with OpenPass button to the user and triggering the underlying code when the user clicks Sign In to OpenPass.
<a href="{{authorizeUrl}}">Sign In to OpenPass</a>
Example call to the authorize endpoint
The following example shows a call to the authorize endpoint with all required parameters and values.
https://auth.myopenpass.com/v1/api/authorize?response_type=code&client_id=29352915982374239857&scope=openid&state=97166977ea60581eee4a701a4287f656&code_challenge_method=S256&code_challenge=f_I4cgCYHdurO9gHjtAtkOb3fzybXNX-_B2VW2M8iNs&redirect_uri=https%3A%2F%2Fsite.opw1.net%2Fredirect-callback
Exchange authorization code for tokens
In the redirect flow, after the user has navigated to the authorize URL, several things can happen:
- The user signs in successfully. See Successful sign-in.
- Sign-in fails because an error occurs during the sign-in process (either transient, such as network connectivity, or due to user error). See Unsuccessful sign-in.
- Sign-in fails because the user cancels the sign-in by closing the page or navigating backwards. See Unsuccessful sign-in.
Successful sign-in
The following is the sequence of steps for a successful sign-in. When you have a successful result, follow the additional steps to verify the ID token.
- OpenPass redirects the page to the
redirect_urithat was set on the authorize URL. The request includes two parameters on the query string:code: A requirement for the next step to complete the authentication flow and receive authentication tokens.state: A security parameter to help prevent forgery attacks. See state parameter.
- The client must handle the redirect (GET) request to the
redirect_uriand complete the authentication process: a. Verify that thestatevalue you passed to the authorize endpoint matches the one sent in this redirect request. b. If thestatevalue does not match, abort the authentication process and display an error to the user or ask them to sign in again. - The client exchanges the authorization
codevalue for the authentication tokens. When the tokens are verified, the user is authenticated. To do this, the client sends a POST HTTP request to https://auth.myopenpass.com/v1/api/token with a Basic Authorization header (server-side integrations only) and the following parameters (content-type:application/x-www-form-urlencoded):client_id(only if the Basic Authorization header is not included): Your Client ID from OpenPass. Must be the sameclient_idthat you passed to the authorize URL.
NOTE: The Basic Authorization header is required only when supplying a client secret (server-side integration). For client-side integrations where this header is not included, the
client_idparameter is required instead. These options are mutually exclusive.redirect_uri: The sameredirect_urithat you passed to the authorize URL.code: The authorizationcodethat you retrieved from the redirect query string.grant_type: Must be theauthorization_code.code_verifier: Thecode_verifierthat was generated when constructing thecode_challengefor the authorize URL.
NOTE: This request can be issued from the client/browser or on the server side.
The result you get is either a success (200) or an error (400-500) with a JSON body as follows:
- Success
id_token: The identity token JWT.access_token: The access token JWT.token_type: The type of token. For OpenPass, it is alwaysBearer.
- Error
error: The error code.error_description: A description of the error along with any assistance to help resolve it.error_uri: The URI of the error.
The ID token is a JWT that contains information about the authenticated user including the user email address. The access token is also a JWT, but it is used to access protected resources.
To verify the ID token JWT, follow these steps (or use a library such as Verify a JWT from Auth0):
- Get the OpenPass JWKS from https://auth.myopenpass.com/.well-known/jwks.
- Get the Key ID from the ID token JWT headers.
- Get the correct JWK from the JWKS using the Key ID. This is the public signing key for the JWT.
- Verify the JWT signature using the JWK.
- Verify that the algorithm used to generate the JWT is the same algorithm listed in the JWK.
- Verify that the JWT token issuer is
https://auth.myopenpass.com.
Example code for sign-in
The following example is pseudo-code to demonstrate an implementation approach for managing the sign-in process.
void handleOpenPassAuthorizeRedirect(HttpRequest request, String userSessionId) {
var clientId = "123abc";
var redirectUri = urlEncode("https://yoursite.com/handle_op_callback");
var state = getParameter(request.query, "state");
var authCode = getParameter(request.query, "code");
var originalSecurityParameters = this.securityParameterStorage.get(userSessionId);
// Make sure that the state originally generated and passed in the authorize URL
// matches the state on the redirect request.
verifyStateMatch(originalSecurityParameters.state, state);
// The code_verifier is passed to the token endpoint, and is then matched against the code_challenge
// that was passed in to the authorize URL.
var postBodyParameters = new HashMap<String, String>();
parameters["clientId"] = clientId;
parameters["redirect_uri"] = redirectUri;
parameters["code"] = authCode;
parameters["grant_type"] = "authorization_code";
parameters["code_verifier"] = securityParameters.codeVerifier;
var response = http.post("https://auth.myopenpass.com/v1/api/token", postBodyParameters);
var rawIdTokenJwt = response.json()["id_token"];
// When the JWT is verified, we can say that the user is authenticated.
DecodedJWT idToken = verifyIdToken(rawIdTokenJwt);
System.out.println("User email: " + idToken.sub);
}
void verifyIdToken(String rawIdTokenJwt){
// decode JWT to check for valid structure.
DecodedJWT decodedJwt = JWT.decode(rawIdTokenJwt);
// Connect to the OpenPass JWKS provider endpoint to retrieve the JSON web key related to the JWT key id.
JwkProvider jwkProvider = new UrlJwkProvider("https://auth.myopenpass.com/.well-known/jwks");
Jwk jwk = jwkProvider.get(decodedJwt.getKeyId());
// Get the public key from the JWK endpoint and create verification algorithm.
PublicKey publicKey = jwk.getPublicKey();
Algorithm algorithm = Algorithm.RSA256((RSAKey) publicKey);
// verify that the JWT has the expected algorithm and is signed and issued by OpenPass.
JWTVerifier verifier = JWT.require(algorithm).withIssuer("https://auth.myopenpass.com").build();
verifier.verify(decodedJwt);
return decodedJwt;
}
Unsuccessful sign-in
If the sign-in was unsuccessful, you must handle the error redirect. OpenPass redirects to the redirect URI you provided in the redirect_uri parameter on the Authorize URL and includes error details on the query string of that request.
Example unsuccessful response
https://example.com/handle_op_redirect?error=invalid_client&error_description=Client+Does+Not+Exist
Additional resources
For more information, see the following pages:
- API reference
- Security considerations
- Authentication tokens
- UID2
- Integration best practices
- Co-branding guidelines