Skip to content

OAuth user authentication without exposing client secret

License

Notifications You must be signed in to change notification settings

octokit/auth-oauth-user-client.js

 
 

Repository files navigation

auth-oauth-user-client.js

OAuth user authentication without exposing client secret

@latest Build Status

Table of contents

Backend service

auth-oauth-user-client.js requires a backend service to function. @octokit/oauth-app provides compatible Node.js/Express.js/Cloudflare Worker middlewares to support auth-oauth-user-client.js.

Standalone usage

Browsers

Load @octokit/auth-oauth-user-client directly from cdn.skypack.dev

<script type="module">
  import { createOAuthUserClientAuth } from "https://cdn.skypack.dev/@octokit/auth-oauth-user-client";
</script>

Node

Install with npm install @octokit/auth-oauth-user-client

const {
  createOAuthUserClientAuth,
} = require("@octokit/auth-oauth-user-client");
const auth = createOAuthUserClientAuth({
  clientId: "clientId123",
  clientType: "github-app", // defaults to `"oauth-app"`
  expirationEnabled: true, // defaults to `true` for GitHub App, `false` for OAuth App
});

// Get token from local session. Returns `null` when `code` or `state` search
// parameters is missing and no session can be fetched from [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage).
const session = await auth({ type: "getToken" });

// Use `signIn` command to redirect to GitHub when the user is not signed in.
if (!session) await auth({ type: "signIn" });
// `token` can be retrieved from a non-null `session`.
else console.log(session.authentication.token);

Usage with Octokit

Browsers

Load @octokit/auth-oauth-user-client and @octokit/core (or core-compatible module) directly from cdn.skypack.dev

<script type="module">
  import { Octokit } from "https://cdn.skypack.dev/@octokit/core";
  import { createOAuthUserClientAuth } from "https://cdn.skypack.dev/@octokit/auth-oauth-user-client";
</script>

Node

Install with npm install @octokit/core @octokit/auth-oauth-user-client. Optionally replace @octokit/core with a compatible module

const { Octokit } = require("@octokit/core");
const {
  createOAuthUserClientAuth,
} = require("@octokit/auth-oauth-user-client");
const octokit = new Octokit({
  authStrategy: createOAuthUserClientAuth,
  auth: {
    clientId: "clientId123",
    clientType: "github-app", // defaults to `"oauth-app"`
    expirationEnabled: true, // defaults to `true` for GitHub App, `false` for OAuth App
  },
});

const session = await octokit.auth();

// Use `signIn` command to redirect to GitHub when the user is not signed in.
if (!session) await octokit.auth({ type: "signIn" });
// Make GitHub API requests.
else {
  const { data } = await octokit.request("GET /user");
  console.log(data);
}

createOAuthUserClientAuth(options) or new Octokit({auth})

The createOAuthUserClientAuth method accepts a single options object as argument:

name type description
clientId string Required. Find Client ID on the app’s about page in settings.
clientType string Either "oauth-app" or "github-app". Defaults to "oauth-app".
expirationEnabled boolean Defaults to true for GitHub App, false for OAuth App.
session object Initial session, defaults to null. See session object.
defaultScopes string Only relevant for OAuth App. See available scopes.
serviceOrigin string Defaults to location.origin. Required only when the @octokit/oauth-app Node.js/Express.js/Cloudflare middleware is deployed at a different origin.
servicePathPrefix string Defaults to "/api/github/oauth". Required only when the @octokit/oauth-app Node.js/Express.js/Cloudflare middleware is created with custom pathPrefix.
sessionStore object or false Custom store to get/set session object, false to disable session persistence. See custom store.
stateStore object or false Custom store to get/set state string, false to disable state persistence.
request function You can pass in your own @octokit/request instance. For usage with enterprise, set baseUrl to the API root endpoint. See custom request

Custom store

By default, auth-oauth-user-client.js uses localStorage to store JSON serialized session object and state string.

Pass sessionStore or stateStore in createOAuthUserClientAuth(options) (or new Octokit({auth})) to use your custom code to persist session or state.

For example:

const sessionStore = {
  get: async() => { /* return local session or `null` when there is no session */ }
  set: async(session) => {
    if (session == null) { /* delete local session */ }
    else { /* create or update local session */ }
  }
}

const auth = createOAuthUserClientAuth({
  clientId: "clientId123",
  sessionStore
});

Custom request

const { request } = require("@octokit/request");
createOAuthAppAuth({
  clientId: "1234567890abcdef1234",
  request: request.defaults({
    baseUrl: "https://ghe.my-company.com/api/v3",
  }),
});

auth(command)

The async auth() method returned by createOAuthUserClientAuth(options) accepts the following commands:

Command {type: } Optional Arguments
Sign in "signIn"
  • login: "user"
  • allowSignup: false
  • scopes: ["repo"] (only relevant for OAuth Apps)
Get (local) token "getToken"
Create an app token "createToken"
Check a token "checkToken"
Create a scoped access token (for OAuth App) "createScopedToken"
Reset a token "resetToken"
Renewing a user token with a refresh token (for GitHub App with token expiration enabled) "refreshToken"
Delete an app token (sign out) "deleteToken" offline: true (only deletes session from local session store)
Delete an app authorization "deleteAuthorization"

Session object

The async auth(options) method resolves to an object with the following properties:

property type description
authentication object See authentication object

Authentication object

There are three possible types of authentication object:

  1. OAuth APP authentication token
  2. GitHub APP 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

OAuth APP authentication token

name type description
type string "token"
tokenType string "oauth"
clientType string "oauth-app"
clientId string The clientId from the strategy options
token string The user access token
scopes array of strings array of scope names enabled for the token

GitHub APP user authentication token with expiring disabled

name type description
type string "token"
tokenType string "oauth"
clientType string "github-app"
clientId string The clientId from the strategy options
token string The user access token

GitHub APP user authentication token with expiring enabled

name type description
type string "token"
tokenType string "oauth"
clientType string "github-app"
clientId string The clientId from the strategy options
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: 2022-01-01T08:00:0.000Z

auth.hook(request, route, parameters) or auth.hook(request, options)

auth.hook() hooks directly into the request life cycle. It amends the request to authenticate correctly based on the request URL.

The request option is an instance of @octokit/request. The route/options parameters are the same as for the request() method.

auth.hook() can be called directly to send an authenticated request

const { data: user } = await auth.hook(request, "GET /user");

Or it can be passed as option to request().

const requestWithAuth = request.defaults({ request: { hook: auth.hook } });
const { data: user } = await requestWithAuth("GET /user");

Contributing

See CONTRIBUTING.md

License

MIT

About

OAuth user authentication without exposing client secret

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published