Skip to content

Request methods to create and refresh user access tokens for OAuth and GitHub Apps

License

Notifications You must be signed in to change notification settings

octokit/oauth-methods.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

oauth-methods.js

Set of stateless request methods to create, check, reset, refresh, and delete user access tokens for OAuth and GitHub Apps

@latest Build Status

The OAuth endpoints related to user access tokens are not all part of GitHub's REST API and they behave slightly different. The methods exported by `@octokit/normalize the differences so you don't have to.

Usage

Browsers

@octokit/oauth-methods is not meant for browser usage.

Some of the methods will work, but others do not have CORS headers enabled and will fail (exchangeWebFlowCode(), createDeviceCode(), exchangeDeviceCode(), refreshToken()). Also the Client Secret should not be exposed to clients as it can be used for a Person-in-the-middle attack.

Node

Install with npm install @octokit/core @octokit/oauth-methods

import {
  exchangeWebFlowCode,
  createDeviceCode,
  exchangeDeviceCode,
  checkToken,
  refreshToken,
  scopeToken,
  resetToken,
  deleteToken,
  deleteAuthorization,
} from "@octokit/oauth-methods";

Important

As we use conditional exports, you will need to adapt your tsconfig.json by setting "moduleResolution": "node16", "module": "node16".

See the TypeScript docs on package.json "exports".
See this helpful guide on transitioning to ESM from @sindresorhus

OAuth Web Flow

After a user granted access to an OAuth App or GitHub App on Step 1 of GitHub's OAuth Web Flow, they get redirected to a URL controlled by your app with a ?code=... query parameter.

You can exchange that code for a user access token as described in Step 2 of GitHub's OAuth Web Flow.

Setting clientType is required because there are slight differences between "oauth-app" and "github-app". Most importantly, GitHub Apps do not support scopes.

const { data, authentication } = await exchangeWebFlowCode({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  clientSecret: "1234567890abcdef12347890abcdef12345678",
  code: "code123",
  scopes: ["repo"],
});

data is the raw response data. authentication is a User Authentication object.

OAuth Device Flow

In step 1 of GitHub's OAuth Device Flow, you need to create a device and user code

const {
  data: { device_code, user_code, verification_uri },
} = await createDeviceCode({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  scopes: ["repo"],
});

In step 2 of GitHub's OAuth Device Flow, the user has to enter user_code on verification_uri (https://github.com/login/device unless you use GitHub Enterprise Server).

Once the user entered the code and granted access, you can exchange the device_code for a user access token in step 3 of GitHub's OAuth Device Flow

const { data, authentication } = await exchangeDeviceCode({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  code: device_code,
});

data is the raw response data. authentication is a User Authentication object.

Methods

getWebFlowAuthorizationUrl()

This is a wrapper around @octokit/oauth-authorization-url that accepts a request option instead of baseUrl for consistency with the other OAuth methods. getWebFlowAuthorizationUrl() is a synchronous method and does not send any request.

const { url } = getWebFlowAuthorizationUrl({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  scopes: ["repo"],
});

Options

name type description
clientId string Required. The client ID you received from GitHub when you registered.
clientType string Required. Must be set to either "oauth-app" or "github-app".
redirectUrl string The URL in your application where users will be sent after authorization. See Redirect URLs in GitHub’s Developer Guide.
login string Suggests a specific account to use for signing in and authorizing the app.
scopes array of strings

Only relevant if clientType is set to "oauth-app".

An array of scope names (or: space-delimited list of scopes). If not provided, scope defaults to an empty list for users that have not authorized any scopes for the application. For users who have authorized scopes for the application, the user won't be shown the OAuth authorization page with the list of scopes. Instead, this step of the flow will automatically complete with the set of scopes the user has authorized for the application. For example, if a user has already performed the web flow twice and has authorized one token with user scope and another token with repo scope, a third web flow that does not provide a scope will receive a token with user and repo scope.

Defaults to [].

state string An unguessable random string. It is used to protect against cross-site request forgery attacks. Defaults to Math.random().toString(36).substr(2).
allowSignup boolean Whether or not unauthenticated users will be offered an option to sign up for GitHub during the OAuth flow. Use false in the case that a policy prohibits signups. Defaults to true.
request function You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:
import { request } from "@octokit/request";
const { url } = getWebFlowAuthorizationUrl({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  scopes: ["repo"],
  request: request.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

The getWebFlowAuthorizationUrl method is synchronous and returns an object with the following properties.

name type description
allowSignup boolean Returns options.allowSignup if it was set. Defaults to true.
clientType string Returns options.clientType
clientId string Returns options.clientId.
login string Returns options.login if it was set. Defaults to null.
redirectUrl string Returns options.redirectUrl if it was set. Defaults to null.
scopes array of strings

Only set if options.clientType is set to "oauth-app".

Returns an array of strings. Returns options.scopes if it was set and turns the string into an array if a string was passed, otherwise [].

state string Returns options.state if it was set. Defaults to Math.random().toString(36).substr(2).
url string The authorization URL

exchangeWebFlowCode()

const { data, authentication } = await exchangeWebFlowCode({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  clientSecret: "1234567890abcdef12347890abcdef12345678",
  code: "code123",
});

Options

name type description
clientType string Required. Must be set to either "oauth-app" or "github-app"
clientId string Required. Your app's client ID
clientSecret string Required. One of your app's client secrets
code string Required. The code from GitHub's OAuth flow redirect's ?code=... query parameter
redirectUrl string The redirectUrl option you passed to getWebFlowAuthorizationUrl()
request function You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:
import { request } from "@octokit/request";
const { data, authentication } = await exchangeWebFlowCode({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  clientSecret: "1234567890abcdef12347890abcdef12345678",
  code: "code123",
  request: request.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

Resolves with an @octokit/request response object for POST /login/oauth/access_token (JSON) with an additional authentication key which is the authentication object.

createDeviceCode()

const { data, authentication } = await createDeviceCode({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  scopes: ["repo"],
});

Options

name type description
clientType string Required. Must be set to either "oauth-app" or "github-app"
clientId string Required. Your app's client ID
scopes array of strings

Only permitted if clientType is set to "oauth-app". GitHub Apps do not support scopes.

Array of scope names you want to request for the user access token.

request function You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:
import { request } from "@octokit/request";
const { data } = await createDeviceCode({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  scopes: ["repo"],
  request: request.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

Resolves with an @octokit/request response object for POST https://github.com/login/device/code (JSON).

exchangeDeviceCode()

const { data, authentication } = await exchangeDeviceCode({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  code: "code123",
});
name type description
clientType string Required. Must be set to either "oauth-app" or "github-app"
clientId string Required. Your app's client ID
code string Required. The device_code from the createDeviceCode() response
request function You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:
import { request } from "@octokit/request";
const { data, authentication } = await exchangeDeviceCode({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  code: "code123",
  request: request.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

checkToken()

const { data, authentication } = await checkToken({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  clientSecret: "1234567890abcdef12347890abcdef12345678",
  token: "usertoken123",
});

Options

name type description
clientType string Required. Must be set to either "oauth-app" or "github-app"
clientId string Required. Your app's client ID
clientSecret string Required. One of your app's client secrets
token string Required. The user access token to check
request function You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:
import { request } from "@octokit/request";
const { data, authentication } = await checkToken({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  clientSecret: "1234567890abcdef12347890abcdef12345678",
  token: "usertoken123",
  request: request.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

Resolves with an @octokit/request response object for POST /applications/{client_id}/token with an additional authentication key which is the authentication object. Note that the authentication object will not include the keys for expiring authentication.

refreshToken()

Expiring user access tokens are currently in preview. You can enable them for any of your GitHub apps. OAuth Apps do not support expiring user access tokens

When a user access token expires it can be refreshed using a refresh token. Refreshing a token invalidates the current user access token.

const { data, authentication } = await refreshToken({
  clientType: "github-app",
  clientId: "lv1.1234567890abcdef",
  clientSecret: "1234567890abcdef12347890abcdef12345678",
  refreshToken: "r1.refreshtoken123",
});

Options

name type description
clientType string Must be set to "github-app"
clientId string Required. Your app's client ID
clientSecret string Required. One of your app's client secrets
refreshToken string Required. The refresh token that was received alongside the user access token.
request function You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:
import { request } from "@octokit/request";
const { data, authentication } = await refreshToken({
  clientType: "github-app",
  clientId: "lv1.1234567890abcdef",
  clientSecret: "1234567890abcdef12347890abcdef12345678",
  refreshToken: "r1.refreshtoken123",
  request: request.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

Resolves with an @octokit/request response object for POST /login/oauth/access_token with an additional authentication key which is the GitHub App expiring user authentication.

scopeToken()

const { data, authentication } = await scopeToken({
  clientType: "github-app",
  clientId: "lv1.1234567890abcdef",
  clientSecret: "1234567890abcdef12347890abcdef12345678",
  token: "usertoken123",
  target: "octokit",
  repositories: ["oauth-methods.js"],
  permissions: {
    issues: "write",
  },
});

Options

name type description
clientType string Required. Must be set to "github-app".
clientId string Required. Your app's client ID
clientSecret string Required. One of your app's client secrets
target string Required unless targetId is set. The name of the user or organization to scope the user-to-server access token to.
targetId integer Required unless target is set. The ID of the user or organization to scope the user-to-server access token to.
repositories array of strings The list of repository names to scope the user-to-server access token to. repositories may not be specified if repository_ids is specified.
repository_ids array of integers The list of repository IDs to scope the user-to-server access token to. repositories may not be specified if repositories is specified.
permissions object The permissions granted to the user-to-server access token. See GitHub App Permissions.
request function You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:
import { request } from "@octokit/request";
const { data, authentication } = await scopeToken({
  clientType: "github-app",
  clientId: "lv1.1234567890abcdef",
  token: "usertoken123",
  target: "octokit",
  repositories: ["oauth-methods.js"],
  permissions: {
    issues: "write",
  },
  request: request.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

Resolves with an @octokit/request response object for POST /applications/{client_id}/token/scoped with an additional authentication key which is the new authentication object.

resetToken()

const { data, authentication } = await resetToken({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  clientSecret: "1234567890abcdef12347890abcdef12345678",
  token: "usertoken123",
});

Options

name type description
clientType string Must be set to "oauth-app" or "github-app".
clientId string Required. Your app's client ID
clientSecret string Required. One of your app's client secrets
token string Required. The user access token to reset
request function You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:
import { request } from "@octokit/request";
const { data, authentication } = await resetToken({
  clientId: "1234567890abcdef1234",
  clientSecret: "secret",
  token: "usertoken123",
  request: request.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

Resolves with an @octokit/request response object for POST /applications/{client_id}/token with an additional authentication key which is the new authentication object.

deleteToken()

const { status } = await deleteToken({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  clientSecret: "1234567890abcdef12347890abcdef12345678",
  token: "usertoken123",
});

Options

name type description
clientType string Must be set to "oauth-app" or "github-app"
clientId string Required. Your app's client ID
clientSecret string Required. One of your app's client secrets
token string Required. The user access token to delete
request function You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:
import { request } from "@octokit/request";
const { data, authentication } = await deleteToken({
  clientId: "1234567890abcdef1234",
  clientSecret: "secret",
  token: "usertoken123",
  request: request.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

Resolves with an @octokit/request response object for DELETE /applications/{client_id}/token (which is an empty 204 response).

deleteAuthorization()

const { status } = await deleteAuthorization({
  clientType: "oauth-app",
  clientId: "1234567890abcdef1234",
  clientSecret: "1234567890abcdef12347890abcdef12345678",
  token: "usertoken123",
});

Options

name type description
clientType string Must be set to "oauth-app" or "github-app"
clientId string Required. Your app's client ID
clientSecret string Required. One of your app's client secrets
token string Required. A valid user access token for the authorization
request function You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the REST API root endpoint. Example:
import { request } from "@octokit/request";
const { data, authentication } = await deleteAuthorization({
  clientId: "1234567890abcdef1234",
  clientSecret: "secret",
  token: "usertoken123",
  request: request.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

Resolves with an @octokit/request response object for DELETE /applications/{client_id}/grant (which is an empty 204 response).

Authentication object

The authentication object returned by the methods have one of three formats.

  1. OAuth APP authentication token
  2. GitHub APP non-expiring user authentication token with expiring disabled
  3. GitHub APP user authentication token with expiring enabled

The differences are

  1. scopes is only present for OAuth Apps
  2. refreshToken, expiresAt, refreshTokenExpiresAt are only present for GitHub Apps, and only if token expiration is enabled

Note that the clientSecret may not be set when using exchangeDeviceCode() as clientSecret is not required for the OAuth device flow.

OAuth APP authentication

name type description
clientType string "oauth-app"
clientId string The app's Client ID
token string The user access token
scopes array of strings array of scope names enabled for the token

GitHub App with non-expiring user authentication

name type description
clientType string "github-app"
clientId string The app's Client ID
token string The user access token

GitHub App with expiring user authentication

name type description
clientType string "github-app"
clientId string The app's Client ID
token string The user access token
refreshToken string The refresh token
expiresAt string Date timestamp in ISO 8601 standard. Example: 2022-01-01T08:00:0.000Z
refreshTokenExpiresAt string Date timestamp in ISO 8601 standard. Example: 2021-07-01T00:00:0.000Z

Types

import {
  OAuthAppAuthentication,
  GitHubAppAuthentication,
  GitHubAppAuthenticationWithExpiration,
  GetWebFlowAuthorizationUrlOAuthAppOptions,
  GetWebFlowAuthorizationUrlGitHubAppOptions,
  GetWebFlowAuthorizationUrlOAuthAppResult,
  GetWebFlowAuthorizationUrlGitHubAppResult,
  CheckTokenOAuthAppOptions,
  CheckTokenGitHubAppOptions,
  CheckTokenOAuthAppResponse,
  CheckTokenGitHubAppResponse,
  ExchangeWebFlowCodeOAuthAppOptions,
  ExchangeWebFlowCodeGitHubAppOptions,
  ExchangeWebFlowCodeOAuthAppResponse,
  ExchangeWebFlowCodeGitHubAppResponse,
  CreateDeviceCodeOAuthAppOptions,
  CreateDeviceCodeGitHubAppOptions,
  CreateDeviceCodeDeviceTokenResponse,
  ExchangeDeviceCodeOAuthAppOptionsWithoutClientSecret,
  ExchangeDeviceCodeOAuthAppOptions,
  ExchangeDeviceCodeGitHubAppOptionsWithoutClientSecret,
  ExchangeDeviceCodeGitHubAppOptions,
  ExchangeDeviceCodeOAuthAppResponse,
  ExchangeDeviceCodeOAuthAppResponseWithoutClientSecret,
  ExchangeDeviceCodeGitHubAppResponse,
  ExchangeDeviceCodeGitHubAppResponseWithoutClientSecret,
  RefreshTokenOptions,
  RefreshTokenResponse,
  ScopeTokenOptions,
  ScopeTokenResponse,
  ResetTokenOAuthAppOptions,
  ResetTokenGitHubAppOptions,
  ResetTokenOAuthAppResponse,
  ResetTokenGitHubAppResponse,
  DeleteTokenOAuthAppOptions,
  DeleteTokenGitHubAppOptions,
  DeleteTokenResponse,
  DeleteAuthorizationOAuthAppOptions,
  DeleteAuthorizationGitHubAppOptions,
  DeleteAuthorizationResponse,
} from "@octokit/oauth-methods";

Contributing

See CONTRIBUTING.md

License

MIT