Skip to main content

Redirects & custom pages

Control where users land after sign-in, sign-out, and errors using goauth.Pages, Callbacks.Redirect, and Fiber redirects in middleware.

goauth.Pages

Pages: goauth.Pages{
SignIn: "/login", // GET /auth/signin → redirect here
Error: "/login?authError=1",
VerifyRequest: "/check-email", // after OTP/email sent
},
PageWhen used
SignInUser hits /auth/signin without provider
ErrorOAuth/sign-in failure → /login?error=AccessDenied
VerifyRequestAfter POST /auth/signin/otp or email

Fiber serves the SPA login route

app.Get("/login", func(c fiber.Ctx) error {
// serve index.html or SSR login page
return c.SendFile("./dist/index.html")
})

app.Get("/check-email", func(c fiber.Ctx) error {
return c.SendFile("./dist/index.html")
})

Vite/React Router handles /login and /check-email client-side.

OAuth redirect (GitHub, Google, …)

  1. SPA: window.location.href = "/auth/signin/github?callbackUrl=" + encodeURIComponent("/dashboard")
  2. Provider redirects to /auth/callback/github
  3. goauth sets cookie or returns token HTML/JSON
  4. User lands on callbackUrl or Tokens.CallbackPage
Tokens: goauth.TokensConfig{
Enabled: true,
CallbackPage: "https://app.example.com/auth/callback",
},

Callbacks.Redirect — sanitize callbackUrl

Callbacks: goauth.Callbacks{
Redirect: func(ctx context.Context, target, base string) (string, error) {
if strings.HasPrefix(target, base+"/") {
return target, nil
}
return base + "/dashboard", nil
},
},

Fiber middleware redirects (unauthorized)

Send users to login with return URL:

loginRedirect := func(c fiber.Ctx) error {
next := url.QueryEscape(c.OriginalURL())
return c.Redirect().To("/login?next=" + next)
}

app.Get("/app/*",
fiberauth.GuardWithConfig(auth, fiberauth.GuardConfig{
Unauthorized: loginRedirect,
}),
spaHandler,
)

Post-login redirect in SPA

const params = new URLSearchParams(window.location.search);
const next = params.get("next") ?? "/dashboard";
// after successful signInWithPassword():
window.location.href = next;

Sign-out redirect

await fetch("/auth/signout", {
method: "POST",
credentials: "include",
body: new URLSearchParams({ csrfToken }),
});
window.location.href = "/login";

CORS vs redirect

Prefer same-origin proxy (Vite → Fiber) so redirects and cookies stay on one host. If SPA and API differ by origin, enable CORS on Fiber and use bearer tokens instead of cookies.