Test Kinde sign-in locally with a public callback URL
Test Kinde sign-in on localhost with a Horizon tunnel, using a stable HTTPS URL for the allowed callback and logout redirect URLs.
Sign in with Kinde on your laptop, with a callback URL that stays the same across restarts.
Kinde checks the callback URL against the list you set for your application. A stable Horizon URL means you set that list once.
Before you begin
- Node.js 18 or later
- A Horizon account and the CLI (see Getting started)
- A reserved subdomain for
-s. Reserve one on the Subdomains page. - A Kinde account with an application, and a Next.js App Router app
Start a tunnel
Use -s with a subdomain you reserved. Without it, the subdomain is random and changes every run, so the callback URL you save in Kinde would point at a dead URL after a restart. Reserved subdomains are a paid feature, see Pricing.
hrzn tunnel http://localhost:3000 -s my-appHORIZON: Tunnel connected
URL https://my-app.hrzn.run (reserved)
Forwarding http://localhost:3000
Request log https://hrzn.run/dashboard/tunnels/my-appYour public URL is https://my-app.hrzn.run. Keep this terminal open.
The first time you open the URL in a browser, Horizon shows a Before you continue page. Select Continue to site. You see it once every 7 days per IP address, so the redirect back from Kinde won't surprise you later.
Add the URLs in Kinde
- In Kinde, open Settings, then Applications.
- Open your application's details.
- In Allowed callback URLs, enter
https://my-app.hrzn.run/api/auth/callback. - In Allowed logout redirect URLs, enter
https://my-app.hrzn.run. - Save your changes.
Check both fields for spaces before or after the URL. Kinde lists stray spaces as a cause of an invalid callback URL.
Set the app environment variables
Install the Kinde SDK for Next.js.
npm install @kinde-oss/kinde-auth-nextjsSet the site URL and the post-logout URL to the public address. If you leave them at http://localhost:3000, the SDK builds localhost URLs.
KINDE_CLIENT_ID=your_client_id
KINDE_CLIENT_SECRET=your_client_secret
KINDE_ISSUER_URL=your_issuer_url
KINDE_SITE_URL=https://my-app.hrzn.run
KINDE_POST_LOGIN_REDIRECT_URL=/dashboard
KINDE_POST_LOGOUT_REDIRECT_URL=https://my-app.hrzn.runCreate the route handler that serves the SDK's auth routes.
import { handleAuth } from "@kinde-oss/kinde-auth-nextjs/server";
export const GET = handleAuth();Add a sign-in link.
import { LoginLink } from "@kinde-oss/kinde-auth-nextjs/components";
export default function Home() {
return <LoginLink>Sign in</LoginLink>;
}Start the app on port 3000. Restart it after you edit .env.local.
npm run devSign in through the public URL
Open https://my-app.hrzn.run and select Sign in. Start from the public URL so the browser, Kinde and your app agree on the host.
Check it works
Kinde shows its sign-in page. After you sign in, Kinde redirects the browser to https://my-app.hrzn.run/api/auth/callback, and the SDK sends you to /dashboard.
Your Horizon terminal prints a GET line for /api/auth/callback. A 3xx status means your app redirected you onward. If the line shows a 4xx or 5xx, see Troubleshooting.
Troubleshooting
Invalid callback URL
- Check that the value in Allowed callback URLs matches the callback your app sends, character for character.
- Remove spaces before and after the URL.
- Check that
KINDE_CLIENT_IDbelongs to the application you edited.
The callback goes to localhost
KINDE_SITE_URL still holds http://localhost:3000, or the dev server didn't pick up the change. Horizon sets the Host header to localhost:3000 and sends the public host in X-Forwarded-Host, so a framework that builds URLs from Host gets localhost. Set KINDE_SITE_URL to https://my-app.hrzn.run and restart npm run dev.
The tunnel URL changed
You started the tunnel without -s, so Horizon gave you a new random subdomain. Restart with -s my-app and the URL stays the same. -s needs a subdomain you reserved, see Pricing.
Nothing reaches your app
- Check that the Horizon terminal is still running. If its last line is
Connection lost. Reconnecting…, wait forReconnected. - Check that your app listens on port 3000.
Next steps
- Read Kinde's guide to callback URLs.
- Read the Kinde Next.js SDK guide.
Test Firebase Authentication locally with authorized domains
Test Firebase Authentication sign-in on localhost with a Horizon tunnel, and add the tunnel host to the authorized domains once.
Test Okta sign-in locally with an OIDC redirect URI
Test Okta OIDC sign-in on localhost with a Horizon tunnel, and set the sign-in redirect URI on your app integration once.