PingOne Platform APIs

Step 4: Exchange code for token (BASIC AUTH)

 

POST {{authPath}}/{{envID}}/as/token

The token endpoint is used by the client to obtain an access token by presenting the client’s authorization grant. For authorization_code grants, the application calls the POST {{authPath}}/{{envID}}/as/token endpoint to acquire the access token. The request body must include values for the following properties:

  • grant_type

    A string that specifies the grant type of the token request. In this example, the value is authorization_code.

  • code

    A string that specifies the authorization code value returned by the authorization request.

  • redirect_uri

    A string that specifies the URL that specifies the return entry point of the application.

The request requires basic authentication, in which the application ID and secret are the username needed to authenticate the request. In a curl command, you can use the --user parameter to satisfy the basic authentication requirement like this: --user "{{appID}}:{{appSecret}}".

The response data contains the access token and the ID token.

CLIENT_SECRET_BASIC is the industry standard approach used by most OAuth 2.0 implementations.

Headers

Authorization

Content-Type      application/x-www-form-urlencoded

Body

urlencoded ( application/x-www-form-urlencoded )

Key Value

grant_type

authorization_code

code

{{basicAuthCode}}

redirect_uri

http://localhost:3000/callback

Example Request

  • cURL

  • C#

  • Go

  • HTTP

  • Java

  • jQuery

  • NodeJS

  • Python

  • PHP

  • Ruby

  • Swift

curl --location --globoff '{{authPath}}/{{envID}}/as/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Basic e3tzaGFyZWRXZWJBcHBJRH19Ont7c2hhcmVkV2ViQXBwU2VjcmV0fX0=' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code={{basicAuthCode}}' \
--data-urlencode 'redirect_uri=http://localhost:3000/callback'
var options = new RestClientOptions("{{authPath}}/{{envID}}/as/token")
{
  MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("", Method.Post);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Authorization", "Basic e3tzaGFyZWRXZWJBcHBJRH19Ont7c2hhcmVkV2ViQXBwU2VjcmV0fX0=");
request.AddParameter("grant_type", "authorization_code");
request.AddParameter("code", "{{basicAuthCode}}");
request.AddParameter("redirect_uri", "http://localhost:3000/callback");
RestResponse response = await client.ExecuteAsync(request);
Console.WriteLine(response.Content);
package main

import (
  "fmt"
  "strings"
  "net/http"
  "io"
)

func main() {

  url := "{{authPath}}/{{envID}}/as/token"
  method := "POST"

  payload := strings.NewReader("grant_type=authorization_code&code=%7B%7BbasicAuthCode%7D%7D&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback")

  client := &http.Client {
  }
  req, err := http.NewRequest(method, url, payload)

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
  req.Header.Add("Authorization", "Basic e3tzaGFyZWRXZWJBcHBJRH19Ont7c2hhcmVkV2ViQXBwU2VjcmV0fX0=")

  res, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer res.Body.Close()

  body, err := io.ReadAll(res.Body)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(string(body))
}
POST /{{envID}}/as/token HTTP/1.1
Host: {{authPath}}
Content-Type: application/x-www-form-urlencoded
Authorization: Basic e3tzaGFyZWRXZWJBcHBJRH19Ont7c2hhcmVkV2ViQXBwU2VjcmV0fX0=

grant_type=authorization_code&code=%7B%7BbasicAuthCode%7D%7D&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback
OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "grant_type=authorization_code&code={{basicAuthCode}}&redirect_uri=http://localhost:3000/callback");
Request request = new Request.Builder()
  .url("{{authPath}}/{{envID}}/as/token")
  .method("POST", body)
  .addHeader("Content-Type", "application/x-www-form-urlencoded")
  .addHeader("Authorization", "Basic e3tzaGFyZWRXZWJBcHBJRH19Ont7c2hhcmVkV2ViQXBwU2VjcmV0fX0=")
  .build();
Response response = client.newCall(request).execute();
var settings = {
  "url": "{{authPath}}/{{envID}}/as/token",
  "method": "POST",
  "timeout": 0,
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded",
    "Authorization": "Basic e3tzaGFyZWRXZWJBcHBJRH19Ont7c2hhcmVkV2ViQXBwU2VjcmV0fX0="
  },
  "data": {
    "grant_type": "authorization_code",
    "code": "{{basicAuthCode}}",
    "redirect_uri": "http://localhost:3000/callback"
  }
};

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require('request');
var options = {
  'method': 'POST',
  'url': '{{authPath}}/{{envID}}/as/token',
  'headers': {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Authorization': 'Basic e3tzaGFyZWRXZWJBcHBJRH19Ont7c2hhcmVkV2ViQXBwU2VjcmV0fX0='
  },
  form: {
    'grant_type': 'authorization_code',
    'code': '{{basicAuthCode}}',
    'redirect_uri': 'http://localhost:3000/callback'
  }
};
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});
import requests

url = "{{authPath}}/{{envID}}/as/token"

payload = 'grant_type=authorization_code&code=%7B%7BbasicAuthCode%7D%7D&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback'
headers = {
  'Content-Type': 'application/x-www-form-urlencoded',
  'Authorization': 'Basic e3tzaGFyZWRXZWJBcHBJRH19Ont7c2hhcmVkV2ViQXBwU2VjcmV0fX0='
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)
<?php
require_once 'HTTP/Request2.php';
$request = new HTTP_Request2();
$request->setUrl('{{authPath}}/{{envID}}/as/token');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
  'follow_redirects' => TRUE
));
$request->setHeader(array(
  'Content-Type' => 'application/x-www-form-urlencoded',
  'Authorization' => 'Basic e3tzaGFyZWRXZWJBcHBJRH19Ont7c2hhcmVkV2ViQXBwU2VjcmV0fX0='
));
$request->addPostParameter(array(
  'grant_type' => 'authorization_code',
  'code' => '{{basicAuthCode}}',
  'redirect_uri' => 'http://localhost:3000/callback'
));
try {
  $response = $request->send();
  if ($response->getStatus() == 200) {
    echo $response->getBody();
  }
  else {
    echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
    $response->getReasonPhrase();
  }
}
catch(HTTP_Request2_Exception $e) {
  echo 'Error: ' . $e->getMessage();
}
require "uri"
require "net/http"

url = URI("{{authPath}}/{{envID}}/as/token")

http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Type"] = "application/x-www-form-urlencoded"
request["Authorization"] = "Basic e3tzaGFyZWRXZWJBcHBJRH19Ont7c2hhcmVkV2ViQXBwU2VjcmV0fX0="
request.body = "grant_type=authorization_code&code=%7B%7BbasicAuthCode%7D%7D&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback"

response = http.request(request)
puts response.read_body
let parameters = "grant_type=authorization_code&code=%7B%7BbasicAuthCode%7D%7D&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback"
let postData =  parameters.data(using: .utf8)

var request = URLRequest(url: URL(string: "{{authPath}}/{{envID}}/as/token")!,timeoutInterval: Double.infinity)
request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.addValue("Basic e3tzaGFyZWRXZWJBcHBJRH19Ont7c2hhcmVkV2ViQXBwU2VjcmV0fX0=", forHTTPHeaderField: "Authorization")

request.httpMethod = "POST"
request.httpBody = postData

let task = URLSession.shared.dataTask(with: request) { data, response, error in
  guard let data = data else {
    print(String(describing: error))
    return
  }
  print(String(data: data, encoding: .utf8)!)
}

task.resume()

Example Response

200 OK

{
    "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImRlZmF1bHQ",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "openid",
    "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImRlZmF1bHQifQ"
}