Skip to content

OAuth 2.0 Grant Types

RFC 6749 describes a number of "grants" for a client application to acquire an access token. You can consider a grant similar to a "workflow" that is targeted for a specific scenario of use cases.

Authorization Code Grant Type

Defined in: Section 4.1 of RFC 6749.

Model requirements: Model for Authorization Code Grant

An authorization code is a credential representing the resource owner's authorization (to access its protected resources) which is used by the client to obtain an access token.

Refresh Token Grant Type

Defined in: Section 6 of RFC 6749.

Model requirements: Model for Refresh Code Grant

If the authorization server issued a refresh token to the client, the client can request a refresh of their authorization token.

Password Grant Type

WARNING

Password grant type is deprecated and should not be used at all. Use this type only for legacy support and consider it inherently unsafe. Read more in the following resources:

Defined in: Section 4.3 of RFC 6749.

Model requirements: Model for Password Grant

The password grant is suitable for clients capable of obtaining the resource owner's credentials ( username and password, typically using an interactive form).

Client Credentials Grant Type

Defined in: Section 4.4 of RFC 6749.

Model requirements: Model for Refresh Token Code Grant

The client can request an access token using only its client credentials (or other supported means of authentication) when requesting access to the protected resources under its control. The client credentials grant type must only be used by confidential clients.

Extension Grants

Defined in: Section 4.5 of RFC 6749.

Create a subclass of AbstractGrantType and create methods handle and saveToken along with other required methods according to your needs:

const OAuth2Server = require('@node-oauth/oauth2-server');
const {
  AbstractGrantType,
  InvalidArgumentError,
  InvalidRequestError
} = OAuth2Server;

class MyCustomGrantType extends AbstractGrantType {
    constructor(opts) {
        super(opts);
    }

    async handle(request, client) {
        if (!request) throw new InvalidArgumentError('Missing `request`');
        if (!client) throw new InvalidArgumentError('Missing `client`');

        let scope = this.getScope(request);
        let user = await this.getUserBySomething(request);

        return this.saveToken(user, client, scope);
    }

    async saveToken(user, client, scope) {
        this.validateScope(user, client, scope);

        let token = {
            accessToken: await this.generateAccessToken(client, user, scope),
            accessTokenExpiresAt: this.getAccessTokenExpiresAt(),
            refreshToken: await this.generateRefreshToken(client, user, scope),
            refreshTokenExpiresAt: this.getRefreshTokenExpiresAt(),
            scope: scope
        };

        return this.model.saveToken(token, client, user);
    }

    async getUserBySomething(request) {
        //Get user's data by corresponding data (FB User ID, Google, etc.), etc.
    }
}

module.exports = MyCustomGrantType;

Extension grants are registered through OAuth2Server#token ( options.extendedGrantTypes).

This might require you to approve the new grant_type for a particular client if you do checks on valid grant types.