- Notifications
You must be signed in to change notification settings - Fork26
GitHub OAuth toolset for Node.js
License
octokit/oauth-app.js
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
GitHub OAuth toolset for Node.js
Table of contents
- Usage
- Examples
OAuthApp.defaults(options)
- Constructor options
app.on(eventName, eventHandler)
app.octokit
app.getUserOctokit(options)
app.getWebFlowAuthorizationUrl(options)
app.createToken(options)
app.checkToken(options)
app.resetToken(options)
app.refreshToken(options)
app.scopeToken(options)
app.deleteToken(options)
app.deleteAuthorization(options)
- Middlewares
- Contributing
- License
Browsers |
|
---|---|
Node | Install with |
Important
As we useconditional exports, you will need to adapt yourtsconfig.json
by setting"moduleResolution": "node16", "module": "node16"
.
See the TypeScript docs onpackage.json "exports".
See thishelpful guide on transitioning to ESM from@sindresorhus
import{OAuthApp,createNodeMiddleware}from"@octokit/oauth-app";import{createServer}from"node:http";constapp=newOAuthApp({clientType:"oauth-app",clientId:"1234567890abcdef1234",clientSecret:"1234567890abcdef1234567890abcdef12345678",});app.on("token",async({ token, octokit})=>{const{ data}=awaitoctokit.request("GET /user");console.log(`Token retrieved for${data.login}`);});createServer(createNodeMiddleware(app)).listen(3000);// can now receive user authorization callbacks at /api/github/oauth/callback// See all endpoints at https://github.com/octokit/oauth-app.js#middlewares
GitHub Apps do not supportscopes
. If the GitHub App has expiring user tokens enabled, the token used for theoctokit
instance will be refreshed automatically, and the additional refresh-related properties will be passed to the"token"
event handler.
import{OAuthApp,createNodeMiddleware}from"@octokit/oauth-app";import{createServer}from"node:http";constapp=newOAuthApp({clientType:"github-app",clientId:"lv1.1234567890abcdef",clientSecret:"1234567890abcdef1234567890abcdef12345678",});app.on("token",async({ token, octokit, expiresAt})=>{const{ data}=awaitoctokit.request("GET /user");console.log(`Token retrieved for${data.login}`);});createServer(createNodeMiddleware(app)).listen(3000);// can now receive user authorization callbacks at /api/github/oauth/callback// See all endpoints at https://github.com/octokit/oauth-app.js#middlewares
- Node server with static files served from
public/
folder, hosted on Glitch:https://glitch.com/~github-oauth-client - Serverless functions, hosted onZeit's now:https://github.com/gr2m/octokit-oauth-app-now-example
- Serverless functions, hosted on AWS (viabegin.com):https://github.com/gr2m/octokit-oauth-app-begin-example/
Create a newOAuthApp
with custom defaults for theconstructor options
constMyOAuthApp=OAuthApp.defaults({Octokit:MyOctokit,});constapp=newMyOAuthApp({ clientId, clientSecret});// app.octokit is now an instance of MyOctokit
name | type | description |
---|---|---|
clientId | number | Required. FindClient ID on the app’s about page in settings. |
clientSecret | number | Required. FindClient Secret on the app’s about page in settings. |
clientType | string | Either"oauth-app" or"github-app" . Defaults to"oauth-app" . |
allowSignup | boolean | Sets the default value forapp.getWebFlowAuthorizationUrl(options) . |
redirectUrl | string | The URL in your application where users will be sent after authorization. SeeRedirect URLs in GitHub’s Developer Guide. |
defaultScopes | Array of strings | Only relevant when Sets the default |
log | object | Used for internal logging. Defaults toconsole . |
Octokit | Constructor | You can pass in your own Octokit constructor with custom defaults and plugins. The Octokit Constructor must use an authentication strategy that is compatible with`@octokit/auth-oauth-app. For usage with enterprise, set import{Octokit}from"@octokit/core";newOAuthApp({clientId:"1234567890abcdef1234",clientSecret:"1234567890abcdef1234567890abcdef12345678",Octokit:Octokit.defaults({baseUrl:"https://ghe.my-company.com/api/v3",}),}); Defaults to |
Called whenever a new OAuth access token is created for a user. It accepts two parameters, an event name and a function with one argument
app.on("token.created",async(context)=>{const{ data}=awaitcontext.octokit.request("GET /user");app.log.info(`New token created for${data.login}`);});
TheeventName
can be one of (or an array of)
token.created
token.reset
token.refreshed
(GitHub Apps only)token.scoped
(GitHub Apps only)token.deleted
authorization.deleted
All event handlers are awaited before continuing.
context
can have the following properties
property | type | description |
---|---|---|
context.name | string | Name of the event. One of:token ,authorization |
context.action | string | Action of the event. One of:created ,reset ,deleted |
context.authentication | object | The OAuth authentication object. Seehttps://github.com/octokit/auth-oauth-user.js/#authentication-object |
context.octokit | Octokit instance | Authenticated instance using the The |
Octokit instance withOAuth App authentication. UsesOctokit
constructor option
constoctokit=awaitapp.getUserOctokit({code:"code123"});
options
are the same as inapp.createToken(options)
Theoctokit
instance is authorized using the user access token if the app is an OAuth app and a user-to-server token if the app is a GitHub app. If the token expires it will be refreshed automatically.
Returns and object with all options and aurl
property which is the authorization URL. Seehttps://github.com/octokit/oauth-methods.js/#getwebflowauthorizationurl
const{ url}=app.getWebFlowAuthorizationUrl({state:"state123",scopes:["repo"],});
name | type | description |
---|---|---|
redirectUrl | string | The URL in your application where users will be sent after authorization. SeeRedirect 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 | 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. |
state | string | An unguessable random string. It is used to protect against cross-site request forgery attacks. Defaults toMath.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. The default istrue . Usefalse in the case that a policy prohibits signups. |
The method can be used for both, theOAuth Web Flow and theOAuth Device Flow.
For the web flow, you have to pass thecode
from URL redirect described instep 2.
const{ token}=awaitapp.createToken({code:"code123",});
name | type | description |
---|---|---|
code | string | Required. Pass the code that was passed as?code query parameter in the authorization redirect URL. |
state | string | Required. Pass the state that was passed as?state query parameter in the authorization redirect URL. |
Resolves with anuser authentication object
For the device flow, you have to pass aonVerification
callback function, which prompts the user to enter the received user code at the received authorization URL.
name | type | description |
---|---|---|
onVerification | function | Required. A function that is called once the device and user codes were retrieved The constauth=createOAuthUserAuth({clientId:"1234567890abcdef1234",clientSecret:"1234567890abcdef1234567890abcdef12345678",onVerification(verification){console.log("Open %s",verification.verification_uri);console.log("Enter code: %s",verification.user_code);awaitprompt("press enter when you are ready to continue");},}); |
scopes | array of strings | Only relevant if Array of OAuth scope names that the user access token should be granted. Defaults to no scopes ( |
Resolves with anuser authentication object
try{const{ created_at, app, user}=awaitapp.checkToken({ token});console.log(`token valid, created on %s by %s for %s`,created_at,user.login,app.name,);}catch(error){// token invalid or request error}
name | type | description |
---|---|---|
token | string | Required. |
Resolves with response body from"Check a token" request with an additionalauthentication
property which is auser authentication object.
const{ data, authentication}=awaitapp.resetToken({token:"token123",});// "token123" is no longer valid. Use `token` instead
name | type | description |
---|---|---|
token | string | Required. |
Resolves with response body from"Reset a token" request with an additionalauthentication
property which is auser authentication object.
Expiring tokens are only supported by GitHub Apps, and only if expiring user tokens are enabled.
const{ data, authentication}=awaitapp.refreshToken({refreshToken:"refreshtoken123",});
name | type | description |
---|---|---|
refreshToken | string | Required. |
Resolves with response body from"Renewing a user token with a refresh token" request (JSON) with an additionalauthentication
property which is auser authentication object.
Scoping a token is only supported by GitHub Apps. "Scoping" in this context means to limit access to a selected installation, with a subset of repositories and permissions.
const{ data, authentication}=awaitapp.scopeToken({clientType:"github-app",clientId:"lv1.1234567890abcdef",clientSecret:"1234567890abcdef12347890abcdef12345678",token:"usertoken123",target:"octokit",repositories:["oauth-app.js"],permissions:{issues:"write",},});
Options
name | type | description |
---|---|---|
target | string | Required unlesstargetId is set. The name of the user or organization to scope the user-to-server access token to. |
targetId | integer | Required unlesstarget 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 ifrepository_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 ifrepositories is specified. |
permissions | object | The permissions granted to the user-to-server access token. SeeGitHub App Permissions. |
Resolves with response body from"Create a scoped access token" request with an additionalauthentication
property which is auser authentication object.
awaitapp.deleteToken({token:"token123",});// "token123" is no longer valid.
name | type | description |
---|---|---|
token | string | Required. |
Resolves with response body from"Delete a token" request.
awaitapp.deleteAuthorization({token:"token123",});// "token123" is no longer valid, and no tokens can be created until the app gets re-authorized.
name | type | description |
---|---|---|
token | string | Required. |
Resolves with response body from"Delete an app authorization" request.
A middleware is a method or set of methods to handle requests for common environments.
By default, all middlewares expose the following routes
Route | Route Description |
---|---|
GET /api/github/oauth/login | Redirects to GitHub's authorization endpoint. Accepts optional?state and?scopes query parameters.?scopes is a comma-separated list ofsupported OAuth scope names |
GET /api/github/oauth/callback | The client's redirect endpoint. This is where thetoken event gets triggered |
POST /api/github/oauth/token | Exchange an authorization code for an OAuth Access token. If successful, thetoken event gets triggered. |
GET /api/github/oauth/token | Check if token is valid. Must authenticate using token inAuthorization header. Uses GitHub'sPOST /applications/{client_id}/token endpoint |
PATCH /api/github/oauth/token | Resets a token (invalidates current one, returns new token). Must authenticate using token inAuthorization header. Uses GitHub'sPATCH /applications/{client_id}/token endpoint. |
PATCH /api/github/oauth/refresh-token | Refreshes an expiring token (invalidates current one, returns new access token and refresh token). Must authenticate using token inAuthorization header. Uses GitHub'sPOST https://github.com/login/oauth/access_token OAuth endpoint. |
POST /api/github/oauth/token/scoped | Creates a scoped token (does not invalidate the current one). Must authenticate using token inAuthorization header. Uses GitHub'sPOST /applications/{client_id}/token/scoped endpoint. |
DELETE /api/github/oauth/token | Invalidates current token, basically the equivalent of a logout. Must authenticate using token inAuthorization header. |
DELETE /api/github/oauth/grant | Revokes the user's grant, basically the equivalent of an uninstall. must authenticate using token inAuthorization header. |
Native http server middleware for Node.js
import{OAuthApp,createNodeMiddleware}from"@octokit/oauth-app";import{createServer}from"node:http";constapp=newOAuthApp({clientType:"oauth-app",clientId:"1234567890abcdef1234",clientSecret:"1234567890abcdef1234567890abcdef12345678",});constmiddleware=createNodeMiddleware(app,{pathPrefix:"/api/github/oauth",});createServer(middleware).listen(3000);// can now receive user authorization callbacks at /api/github/oauth/callback
name | type | description |
---|---|---|
app | OAuthApp instance | Required. |
options.pathPrefix | string | All exposed paths will be prefixed with the provided prefix. Defaults to |
Event handler for web worker environments (Cloudflare workers or Deno).
// worker.jsimport{OAuthApp,createWebWorkerHandler}from"@octokit/oauth-app";constapp=newOAuthApp({clientType:"oauth-app",clientId:"1234567890abcdef1234",clientSecret:"1234567890abcdef1234567890abcdef12345678",});consthandleRequest=createWebWorkerHandler(app,{pathPrefix:"/api/github/oauth",});addEventListener("fetch",(event)=>{event.respondWith(handleRequest(event.request));});// can now receive user authorization callbacks at /api/github/oauth/callback
name | type | description |
---|---|---|
app | OAuthApp instance | Required. |
options.pathPrefix | string | All exposed paths will be prefixed with the provided prefix. Defaults to |
Event handler for AWS Lambda using API Gateway V2 HTTP integration.
// worker.jsimport{OAuthApp,createAWSLambdaAPIGatewayV2Handler,}from"@octokit/oauth-app";constapp=newOAuthApp({clientType:"oauth-app",clientId:"1234567890abcdef1234",clientSecret:"1234567890abcdef1234567890abcdef12345678",});exportconsthandler=createAWSLambdaAPIGatewayV2Handler(app,{pathPrefix:"/api/github/oauth",});// can now receive user authorization callbacks at /api/github/oauth/callback
name | type | description |
---|---|---|
app | OAuthApp instance | Required. |
options.pathPrefix | string | All exposed paths will be prefixed with the provided prefix. Defaults to |
When above middlewares do not meet your needs, you can build your ownusing the exportedhandleRequest
function.
handleRequest
function is an abstract HTTP handler which accepts anOctokitRequest
and returns anOctokitResponse
if the request matches any predefined route.
Different environments (e.g., Node.js, Cloudflare Workers, Deno, etc.) exposes different APIs when processing HTTP requests (e.g.,
IncomingMessage
for Node.js,Request
for Cloudflare workers, etc.). Two HTTP-related types (OctokitRequest
andOctokitResponse
) are generalized to make an abstract HTTP handler possible.
To share the behavior and capability with the existing Node.js middleware (and be compatible withOAuth user authentication strategy in the browser), it is better to implement your HTTP handler/middleware based onhandleRequest
function.
handleRequest
function takes three parameters:
name | type | description |
---|---|---|
app | OAuthApp instance | Required. |
options.pathPrefix | string | All exposed paths will be prefixed with the provided prefix. Defaults to |
request | OctokitRequest | Generalized HTTP request in `OctokitRequest` type. |
Implementing an HTTP handler/middleware for a certain environment involves three steps:
- Write a function to parse the HTTP request (e.g.,
IncomingMessage
in Node.js) into anOctokitRequest
object. Seenode/parse-request.ts
for reference. - Write a function to render an
OctokitResponse
object (e.g., asServerResponse
in Node.js). Seenode/send-response.ts
for reference. - Expose an HTTP handler/middleware in the dialect of the environment which performs three steps:
- Parse the HTTP request using (1).
- Process the
OctokitRequest
object usinghandleRequest
. - Render the
OctokitResponse
object using (2).
About
GitHub OAuth toolset for Node.js
Topics
Resources
License
Code of conduct
Security policy
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.