Intro
Use Whop OAuth to authenticate users in your web or iOS app.
This guide only covers the basic steps to implement Whop OAuth and does not cover best practices regarding the OAuth2 protocol. It is recommended to use a library to handle the OAuth2 flow.
We are going to release a guide on how to implement Whop OAuth with auth.js soon.
Step 1: Create a Whop App and obtain secrets
-
Go to the Whop Dashboard and create a new app or select an existing one.
-
Add a redirect uri in your apps OAuth settings
To test your app locally you can add a redirect uri on http://localhost:{PORT}
but it is recommended to use https for production.
-
Copy the app id and api key and set them in your environment variables.
Keep in mind that the api key is a secret and should not be shared with anyone. The app id is public and can be shared with anyone.
NEXT_PUBLIC_WHOP_APP_ID=your-app-id
WHOP_API_KEY=your-api-key
Step 2: Initiate the OAuth flow
Setup the OAuth flow
To follow this guide you will need to install the @whop/api
package from npm:
Start off by creating a route that will be hit by the user when they click the Login with Whop
button:
import { WhopServerSdk } from "@whop/api";
const whopApi = WhopServerSdk({
appApiKey: process.env.WHOP_API_KEY!,
appId: process.env.NEXT_PUBLIC_WHOP_APP_ID,
});
export function GET(request: Request) {
const url = new URL(request.url);
const next = url.searchParams.get("next") ?? "/home";
const { url, state } = whopApi.oauth.getAuthorizationUrl({
// This has to be defined in the redirect uris outlined in step 1.2
redirectUri: "http://localhost:3000/api/oauth/callback",
// These are the authorization scopes you want to request from the user.
scope: ["read_user"],
});
// The state is used to restore the `next` parameter after the user lands on the callback route.
// Note: This is not a secure way to store the state and for demonstration purposes only.
return Response.redirect(url, {
headers: {
"Set-Cookie": `oauth-state.${state}=${encodeURIComponent(
next
)}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=3600`,
},
});
}
Read more about available scopes here.
Now continue by adding a link to your app that will initiate the Login with Whop
flow:
<a href="/api/oauth/init?next=/home">Login with Whop</a>
Upon clicking the link the user will be redirected to the Whop OAuth page and is prompted to authorize your app.
Step 3: Exchange the code for a token
Upon successful authorization the user will be redirected to the redirect uri you specified in the query parameters with code
and state
query parameters:
/api/oauth/callback/route.ts
import { WhopServerSdk } from "@whop/api";
const whopApi = WhopServerSdk({
appApiKey: process.env.WHOP_API_KEY!,
appId: process.env.NEXT_PUBLIC_WHOP_APP_ID,
});
export function GET(request: Request) {
const url = new URL(request.url);
const code = url.searchParams.get("code");
const state = url.searchParams.get("state");
if (!code) {
// redirect to error page
return Response.redirect("/oauth/error?error=missing_code");
}
if (!state) {
// redirect to error page
return Response.redirect("/oauth/error?error=missing_state");
}
const stateCookie = request.headers
.get("Cookie")
?.split(";")
.find((cookie) => cookie.trim().startsWith(`oauth-state.${state}=`));
if (!stateCookie) {
// redirect to error page
return Response.redirect("/oauth/error?error=invalid_state");
}
// exchange the code for a token
const authResponse = await whopApi.oauth.exchangeCode({
code,
redirectUri: "http://localhost:3000/api/oauth/callback",
});
if (!authResponse.ok) {
return Response.redirect("/oauth/error?error=code_exchange_failed");
}
const { access_token } = authResponse.tokens;
// Restore the `next` parameter from the state cookie set in the previous step.
const next = decodeURIComponent(stateCookie.split("=")[1]);
const nextUrl = new URL(next, "http://localhost:3000");
// This is an example, you should not store the plain user auth token in a cookie in production.
// After setting the cookie you can now identify the user by reading the cookie when the user visits your website.
return Response.redirect(nextUrl.toString(), {
headers: {
"Set-Cookie": `whop_access_token=${access_token}; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=3600`,
},
});
}
Implementing with authentication frameworks
Auth.js (coming soon)
We will release an extensive guide on how to implement Whop OAuth with auth.js soon.