Documentation
¶
Overview ¶
Package oauthlogin keeps the state of one redirect login (state, nonce, PKCE verifier, return path) in the server-side session, so the callback verifies it exactly once on any replica sharing the session backend. Shared by the oidc and github providers; its functions are safe for concurrent use.
Index ¶
Constants ¶
const ( CodeLoginFailed = "login_failed" // the code exchange or the verification of its answer failed CodeLoginDenied = "login_denied" // the provider sent error=... (the user or the provider refused) CodeLoginExpired = "login_expired" // no, an expired or an unreadable login state CodeStateMismatch = "state_mismatch" // the callback state does not match the stored one )
The refusal codes of a redirect login; every provider using this package answers them, so a login page handles one set of codes.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type State ¶
type State struct {
State string `json:"state"`
Nonce string `json:"nonce"`
Verifier string `json:"verifier"` // PKCE code verifier: 32 random bytes, base64url (as oauth2.GenerateVerifier)
ReturnPath string `json:"returnPath"` // redirect.ReturnPath(request)
}
State is what a login start stores and its callback needs back.
func Begin ¶
func Begin(ctx context.Context, store *session.Store, writer http.ResponseWriter, request *http.Request, key string) (State, error)
Begin generates State (32 bytes), Nonce (32 bytes) and Verifier and stores them as JSON under key for 10 min, in the session startLoginSession returns.
func Complete ¶
func Complete(ctx context.Context, store *session.Store, request *http.Request, key string) (State, error)
Complete opens the session, pops key (single use) and compares the callback state in constant time. Refusals (*auth.Error): provider sent error=...: ErrUnauthenticated code "login_denied"; no or expired state: ErrInvalidRequest "login_expired"; mismatch: ErrInvalidRequest "state_mismatch"; no code: ErrInvalidRequest. A provider error is refused before the session is read, so it does not consume the state.