Skip to main content

OAuth 2.0 Password Grant Type

Password grant type overview

The OAuth 2.0 Password grant type is a legacy way to exchange a user's username and password for an access token. This grant type is generally not recommended, since it requires a user to enter their credentials to a third-party app within your app.

Additional resources: https://oauth.net/2/grant-types/password/

How does the password grant type work?

At a high level the OAuth 2.0 password flow works like this:

  1. As a software vendor you ask your users for their username and password for a third-party app.
  2. You exchange their credentials for an access token using the third-party's token URL.
  3. You use the access token to access third-party resources the user has access to.

Implementing OAuth 2.0 password grant type in custom components

The password grant type is deprecated, and Prismatic's OAuth 2.0 service does not automatically exchange usernames and passwords for access tokens. That logic will need to be implemented within your custom component.

Whenever an action that calls the third-party app is run, it will need to exchange the username and password for an access token, and then initialize an HTTP client that has that access token.

This example HTTP client code handles the password exchange, and returns an authenticated HTTP client:

import { Connection, util } from "@prismatic-io/spectral";
import { createClient } from "@prismatic-io/spectral/dist/clients/http";

export const createAcmeClient = async (connection: Connection) => {
// Extract necessary fields from connection definition
const { tokenUrl, username, password, client_id, client_secret } =
connection.fields;

// Password grant often requires a client ID / secret base64-encoded as an authorization header
const authHeader = Buffer.from(`${client_id}:${client_secret}`).toString(
"base64",
);

// Create an HTTP client to make a token exchange request
const authClient = createClient({
baseUrl: "https://auth.acme.com",
headers: {
Authorization: `Basic ${authHeader}`,
},
});

// Exchange username/password for an access token
const { data: authResponseData } = await auth.post("/oauth/token", {
grant_type: "password",
username,
password,
});

const { access_token } = authResponseData;

// Return an authenticated HTTP client
return createClient({
baseUrl: "https://api.acme.com",
headers: {
Authorization: `Bearer ${access_token}`,
},
});
};