OAuth 2.0 with PKCE
Most providers require a client ID, client secret, and redirect URI.
import { Google } from "arctic";
const google = new Google(clientId, clientSecret, redirectURI);
Create authorization URL
Generate a state and code verifier using generateState()
and generateCodeVerifier()
. Use them to create an authorization URL with createAuthorizationURL()
, store the state and code verifier as cookies, and redirect the user to the authorization url.
You may optionally pass scopes
. For providers that implement OpenID Connect, openid
is always included. There may be more options depending on the provider.
import { generateCodeVerifier, generateState } from "arctic";
const state = generateState();
const codeVerifier = generateCodeVerifier();
const url = await google.createAuthorizationURL(state, codeVerifier);
// store state verifier as cookie
setCookie("state", state, {
secure: true, // set to false in localhost
path: "/",
httpOnly: true,
maxAge: 60 * 10 // 10 min
});
// store code verifier as cookie
setCookie("code_verifier", codeVerifier, {
secure: true, // set to false in localhost
path: "/",
httpOnly: true,
maxAge: 60 * 10 // 10 min
});
return redirect(url);
Validate authorization code
Compare the state, and use validateAuthorizationCode()
to validate the authorization code with the code verifier. This returns an object with an access token, an ID token for OIDC, and a refresh token if requested. If the code is invalid, it will throw an OAuth2RequestError
.
import { OAuth2RequestError } from "arctic";
const code = request.url.searchParams.get("code");
const state = request.url.searchParams.get("state");
const storedState = getCookie("state");
const storedCodeVerifier = getCookie("code_verifier");
if (!code || !storedState || !storedCodeVerifier || state !== storedState) {
// 400
throw new Error("Invalid request");
}
try {
const tokens = await google.validateAuthorizationCode(code, storedCodeVerifier);
} catch (e) {
if (e instanceof OAuth2RequestError) {
const { request, message, description } = e;
}
// unknown error
}
Refresh access token
If the OAuth provider supports refresh tokens, refreshAccessToken()
can be used to get a new access token using a refresh token. This will throw an OAuth2RequestError
if the refresh token is invalid.
import { OAuth2RequestError } from "arctic";
try {
const tokens = await google.refreshAccessToken(refreshToken);
} catch (e) {
if (e instanceof OAuth2RequestError) {
const { request, message, description } = e;
}
// unknown error
}