Kraken OAuth
To enable login functionality on a consumer site, you can authenticate with
Kraken as an identity provider instead of directly providing email and password
to the obtainKrakenToken mutation. This approach is particularly beneficial
when customers use the same login for multiple applications, as it allows the
creation of a single login form that can be used independently by different
consuming applications.
This feature is still under development and may change in future. In particular, the logout and session checking functionalities are not yet implemented.
Getting started
This guide is an add-on to the Getting Started guides for setting up Blueprint Auth with the Pages Router and the App Router. If you haven't set up Blueprint Auth yet, follow one of these guides before proceeding. These additional steps will help you integrate Kraken OAuth into your Next.js application.
Configuration
To enable Kraken OAuth, you need to provide the following configuration options:
| Option | Description | Type | Environment variable | Required |
|---|---|---|---|---|
krakenConfig.authEndpoint | The Kraken auth endpoint | string | KRAKEN_AUTH_ENDPOINT | ✅ |
krakenConfig.oauthClientId | The Kraken OAuth client ID | string | KRAKEN_OAUTH_CLIENT_ID | ✅ |
apiRoutes.krakenOAuth | Kraken OAuth API endpoint | string | ✅ |
Environment variables
Define the following environment variables in your .env.local file:
KRAKEN_AUTH_ENDPOINT="Kraken auth endpoint"
KRAKEN_OAUTH_CLIENT_ID="Kraken OAuth client ID"
When deploying to Vercel, configure environment variables in the
Vercel dashboard rather than
committing them to .env files.
The use of environment variables is strongly recommended for supported options.
Configuration object
import { createAuthConfig } from "@krakentech/blueprint-auth";
export const authConfig = createAuthConfig({
apiRoutes: {
krakenOAuth: "/api/auth/kraken-oauth",
},
});
Middleware
The middleware is responsible for protecting routes and refreshing auth tokens.
Make sure the createAuthMiddleware function in your middleware.ts file
receives the required Kraken OAuth configuration options.
API handler
The API handler is responsible for storing auth tokens obtained from the Kraken Authorisation Server API as cookies. It redirects the user to the dashboard page if authentication is successful, or to the login page in case an error occurs.
Create the Kraken OAuth API handler using
createKrakenOAuthHandler.
- Pages Router
- App Router
import { createKrakenOAuthHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";
export default createKrakenOAuthHandler(authConfig);
import { createKrakenOAuthHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";
export const GET = createKrakenOAuthHandler(authConfig);
Server Function
The generateKrakenOAuthURI Server Function is responsible for generating the
Kraken OAuth URI, which is used to initiate the OAuth flow.
Export the generateKrakenOAuthURI function from your Server Function file.
- Pages Router
- App Router
import { createServerSideAuth } from "@krakentech/blueprint-auth/server";
import { authConfig } from "./config";
export const { generateKrakenOAuthURI } = createServerSideAuth(authConfig);
"use server";
import { createAppRouterAuth } from "@krakentech/blueprint-auth/server";
import { cookies, headers } from "next/headers";
import { authConfig } from "./config";
export const { generateKrakenOAuthURI } = createAppRouterAuth(authConfig, {
cookies,
headers,
});
Initiate the OAuth flow
- Pages Router
- App Router
Generate the OAuth URI in the getServerSideProps function of your login page
and pass it to the OAuthButton component.
import type {
GetServerSidePropsContext,
InferGetServerSidePropsType,
} from "next";
import { LoginForm } from "@/components/LoginForm";
import { Button } from "@radix-ui/themes";
export default function LoginPage({
oAuthURI,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
return (
<>
<LoginForm />
<Button asChild>
<a href={oAuthURI} target="_blank">
Log in with Kraken
</a>
</Button>
</>
);
}
export async function getServerSideProps(context: GetServerSidePropsContext) {
const oAuthURI = await generateKrakenOAuthURI({ context });
return { props: { oAuthURI } };
}
The generateKrakenOAuthURI function sets a cookie storing the code verifier.
Since cookies are read-only in Server Components, the function must be used as a
Server Action.
Create an OAuthButton component that uses the generateKrakenOAuthURI Server
Function, and render it on your login page.
"use client";
import { type PropsWithChildren, useTransition } from "react";
import { Button } from "@radix-ui/themes";
import { generateKrakenOAuthURI } from "@/lib/auth/server";
export function OAuthButton({ children }: PropsWithChildren) {
const [isPending, startTransition] = useTransition();
return (
<Button
loading={isPending}
onClick={() => {
startTransition(async () => {
const oAuthURI = await generateKrakenOAuthURI();
window.open(oAuthURI, "_blank");
});
}}
role="link"
>
{children}
</Button>
);
}
import { LoginForm } from "@/components/LoginForm";
import { OAuthButton } from "@/components/OAuthButton";
export default function LoginPage() {
return (
<>
<LoginForm />
<OAuthButton>Log in with Kraken</OAuthButton>
</>
);
}
Learn more about the OAuth flow
Prerequisite values
| Name | Description |
|---|---|
| Client ID | A public identifier for the application. It is unique to the application and is used by the Kraken server to identify the application making the request. It is generated when an application is registered with Kraken. |
| Client Secret | A confidential piece of information known only to the application and the Kraken Authorisation server. It is used in the OAuth flow to authenticate the identity of the application to the server when the application requests to exchange an authorisation code for an access token. |
| Redirect URI | The URL to which the Kraken server will send the user after they have successfully completed authorisation. This must match one of the redirect URIs registered with the application. It is used to ensure that the authorization code is sent to the correct application. |
| Authorize URI | The URL of the Kraken server's authorisation endpoint. The application sends the user to this URL in order to start the authorization process. The Authorize URI includes parameters that tell the Kraken server about the request, including the Client ID, Redirect URI, and Code Challenge. |
In this context, a code challenge is a cryptographic value that the client application generates and sends to the Kraken server as part of the authorization request. The code challenge is used to verify the integrity of the authorization process and prevent certain types of attacks, such as authorization code interception.
Session State
When users authenticate via Kraken OAuth, the session state will reflect the OAuth authentication method:
| Field | Value | Description |
|---|---|---|
authMethod | "oauth" | Indicates user authenticated via Kraken OAuth |
isAuthenticated | true | User has valid authentication |
You can check the authentication method in your components:
const session = await getSession({ context });
if (session.authMethod === "oauth") {
// User authenticated via OAuth
} else if (session.authMethod === "email") {
// User authenticated via email/password
}
FAQ
What happens in generateKrakenOAuthURI?
The generateKrakenOAuthURI Server Function performs the following tasks:
- Generate a unique code verifier and code challenge.
- Store the code verifier in a secure HTTP-only cookie to send with the request headers.
- Create a URI to be navigated to, using the Redirect URI, Client ID and Authorise URI.
How is the OAuth flow initiated?
The OAuth flow is initiated when a user clicks on the "Login with Kraken Auth"
button. The browser navigates to the Kraken URI generated using
generateKrakenOAuthURI, where the user authenticates and authorises the
application.
How is the OAuth flow completed?
After the user authorises the application on the Kraken website, they are redirected back to the Kraken OAuth API route with an authorisation code. The Kraken OAuth API handler then performs the following tasks:
- Retrieve the code verifier from the cookie.
- Send a request to the Kraken token endpoint with the authorisation code and the code verifier to exchange them for an access token and a refresh token.
- Store the access token and the refresh token in secure HTTP-only cookies.
- Redirect the user to the dashboard page upon successful authentication.
How are errors handled?
The serverless function responsible for handling the OAuth flow includes error handling logic via an error handler to deal with authorisation related errors. When an error is caught, the user is redirected to the application's login page by default, where a relevant error message may be displayed.
How are the tokens used?
The access token is used to authenticate all subsequent requests to the Kraken API. The refresh token is used to obtain a new access token when the current one expires. The token expiry value for the cookie is set to the value retrieved in the successful response.
What happens when a token expires?
When the access token expires, a new one is obtained by sending a request to the Kraken token endpoint with the refresh token. If the refresh token also expires, the user is required to login again.
What happens when a user logs out?
When a user logs out, the access token and the refresh token cookies are deleted.