Minimalistic OAuth 2.0 client for Deno. Inspired by js-client-oauth2.
This module tries not to make assumptions on your use-cases. As such, it
Currently supported OAuth 2.0 grants:
import { Application, Router } from "https://deno.land/x/oak@v11.1.0/mod.ts";
import { Session } from "https://deno.land/x/oak_sessions@v4.0.5/mod.ts";
import { OAuth2Client } from "https://deno.land/x/oauth2_client/mod.ts";
const oauth2Client = new OAuth2Client({
clientId: Deno.env.get("CLIENT_ID")!,
clientSecret: Deno.env.get("CLIENT_SECRET")!,
authorizationEndpointUri: "https://github.com/login/oauth/authorize",
tokenUri: "https://github.com/login/oauth/access_token",
redirectUri: "http://localhost:8000/oauth2/callback",
defaults: {
scope: "read:user",
},
});
type AppState = {
session: Session;
};
const router = new Router<AppState>();
router.get("/login", async (ctx) => {
// Construct the URL for the authorization redirect and get a PKCE codeVerifier
const { uri, codeVerifier } = await oauth2Client.code.getAuthorizationUri();
// Store both the state and codeVerifier in the user session
ctx.state.session.flash("codeVerifier", codeVerifier);
// Redirect the user to the authorization endpoint
ctx.response.redirect(uri);
});
router.get("/oauth2/callback", async (ctx) => {
// Make sure the codeVerifier is present for the user's session
const codeVerifier = ctx.state.session.get("codeVerifier");
if (typeof codeVerifier !== "string") {
throw new Error("invalid codeVerifier");
}
// Exchange the authorization code for an access token
const tokens = await oauth2Client.code.getToken(ctx.request.url, {
codeVerifier,
});
// Use the access token to make an authenticated API request
const userResponse = await fetch("https://api.github.com/user", {
headers: {
Authorization: `Bearer ${tokens.accessToken}`,
},
});
const { login } = await userResponse.json();
ctx.response.body = `Hello, ${login}!`;
});
const app = new Application<AppState>();
app.use(Session.initMiddleware());
app.use(router.allowedMethods(), router.routes());
await app.listen({ port: 8000 });
For more examples, check out the examples directory.
v0.*.*
-> v1.*.*
With v1.0.0
:
stateValidator
callbacks to return a Promise, to allow for e.g.
accessing a databaseAuthorizationCodeGrant
and ImplicitGrant
option objects.AuthorizationCodeGrant
GetUriOptions
interface was renamed to AuthorizationUriOptions
getAuthorizationUri(...)
now always returns a Promise<{ uri: URL }>
instead of a plain URL
.
getAuthorizationUri(...)
returns an object containing both an URI and the codeVerifier
that you'll
have to pass to the getToken(...)
call inside the OAuth 2.0 redirection
URI handler. Check out the examples on how to achieve that by using session
cookies.{ disablePkce: true }
to getAuthorizationUri
.ClientCredentialsGrant
GetClientCredentialsTokenOptions
interface was renamed to
ClientCredentialsTokenOptions
ImplicitGrant
GetUriOptions
interface was renamed to ImplicitUriOptions
GetTokenOptions
interface was renamed to ImplicitTokenOptions
ResourceOwnerPasswordCredentialsGrant
GetROPCTokenOptions
interface was renamed to
ResourceOwnerPasswordCredentialsTokenOptions
RefreshTokenGrant