Sign in with credentials (Fiber)
Email + password via providers/credentials. The sign-in endpoint is always:
POST /auth/callback/credentials
Mounted automatically by fiberauth.Handler(auth).
goauth config
import (
"github.com/izetmolla/goauth/providers/credentials"
)
credentials.New(credentials.Options{
Fields: []goauth.CredentialField{
{Name: "email", Label: "Email", Type: "email"},
{Name: "password", Label: "Password", Type: "password"},
},
Authorize: func(ctx context.Context, creds map[string]string, r *http.Request) (*goauth.User, error) {
u, ok := validatePassword(creds["email"], creds["password"])
if !ok {
return nil, nil // invalid credentials
}
return &goauth.User{ID: u.ID, Email: u.Email, Name: u.Name}, nil
},
}),
Browser / form (cookie session)
// Fiber does not need a custom route — POST directly to goauth:
// POST /auth/callback/credentials
// Body: email=...&password=...&csrfToken=...
From a Fiber HTML form you can proxy or redirect:
<form action="/auth/callback/credentials" method="POST">
<input name="email" type="email" />
<input name="password" type="password" />
<input type="hidden" name="csrfToken" value="..." />
<button type="submit">Sign in</button>
</form>
Fetch CSRF first: GET /auth/csrf.
SPA with bearer tokens (recommended for Fiber + React)
Tokens: goauth.TokensConfig{
Enabled: true,
AlwaysReturn: true,
AccessTokenMaxAge: 15 * time.Minute,
RefreshTokenMaxAge: 30 * 24 * time.Hour,
},
TypeScript client
export async function signInWithPassword(email: string, password: string) {
const res = await fetch("/auth/callback/credentials", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Auth-Flow": "token",
Accept: "application/json",
},
body: new URLSearchParams({ email, password }),
});
if (!res.ok) throw new Error(await res.text());
const data = await res.json();
// MFA: if data.challenge → go to MFA screen
localStorage.setItem("goauth", JSON.stringify(data));
return data;
}
Use token on Fiber API routes
const res = await fetch("/api/me", {
headers: { Authorization: `Bearer ${accessToken}` },
});
app.Get("/api/me", fiberauth.Protect(auth), func(c fiber.Ctx) error {
return c.JSON(fiberauth.SessionFrom(c))
})
Fiber app.Test (integration test)
func TestSignIn(t *testing.T) {
app := buildTestApp(t)
body := url.Values{"email": {"admin@example.com"}, "password": {"secret"}}
req, _ := http.NewRequest(http.MethodPost, "/auth/callback/credentials",
strings.NewReader(body.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("X-Auth-Flow", "token")
resp, err := app.Test(req, -1)
if err != nil || resp.StatusCode != http.StatusOK {
t.Fatal(resp.StatusCode)
}
var tok goauth.TokenResponse
json.NewDecoder(resp.Body).Decode(&tok)
req2, _ := http.NewRequest(http.MethodGet, "/api/me", nil)
req2.Header.Set("Authorization", "Bearer "+tok.AccessToken)
resp2, _ := app.Test(req2)
// expect 200
}
Sign out
await fetch("/auth/signout", { method: "POST", credentials: "include" });
// or clear localStorage tokens client-side + discard refresh token
With bearer-only apps, delete stored tokens locally; optionally call signout if you also use cookies.
Refresh token
await fetch("/auth/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({ refresh_token: refreshToken }),
});
See Bearer tokens.