Request authorization code
Before requesting an access token, you need to request an authorization code. This route generates PKCE code verifiers and state tokens for secure authentication, then redirects the user to Ory's authorization server.
- Expressjs
- Go
index.js
app.get("/login", async (req, res) => {
if (!config) {
throw new Error("Config not found")
}
try {
// Generate PKCE code verifier
const code_verifier = client.randomPKCECodeVerifier()
// Calculate code challenge from verifier
const code_challenge =
await client.calculatePKCECodeChallenge(code_verifier)
// Generate state for CSRF protection
const state = client.randomState()
// Store in session for later verification
req.session.codeVerifier = code_verifier
req.session.state = state
// Build authorization parameters
const parameters = {
redirect_uri: process.env.OAUTH_REDIRECT_URI,
scope: "openid email offline_access",
code_challenge,
code_challenge_method: "S256",
state,
}
// Build authorization URL
const redirectTo = client.buildAuthorizationUrl(config, parameters)
// Redirect user to authorization server
console.log("Redirecting to:", redirectTo.href)
res.redirect(redirectTo.href)
} catch (error) {
console.error("Login error:", error)
res.status(500).send(`Login error: ${error.message}`)
}
})
main.go
import (
"crypto/rand"
"encoding/base64"
"net/http"
"time"
"golang.org/x/oauth2"
)
func handleLogin(w http.ResponseWriter, r *http.Request) {
// Generate random state parameter
state, err := generateRandomString(32)
if err != nil {
http.Error(w, "Failed to generate state parameter", http.StatusInternalServerError)
return
}
// Generate code verifier for PKCE
codeVerifier := oauth2.GenerateVerifier()
// Create a new session
sessionID, err := generateRandomString(32)
if err != nil {
http.Error(w, "Failed to generate session ID", http.StatusInternalServerError)
return
}
// Store session
sessions[sessionID] = Session{
State: state,
CodeVerifier: codeVerifier,
}
// Set session cookie
http.SetCookie(w, &http.Cookie{
Name: "session_id",
Value: sessionID,
Path: "/",
HttpOnly: true,
Secure: r.TLS != nil,
MaxAge: int(24 * time.Hour.Seconds()),
})
// Generate authorization URL with PKCE challenge
authURL := oauthConfig.AuthCodeURL(
state,
oauth2.S256ChallengeOption(codeVerifier),
)
// Redirect to authorization server
http.Redirect(w, r, authURL, http.StatusSeeOther)
}
func generateRandomString(length int) (string, error) {
b := make([]byte, length)
if _, err := rand.Read(b); err != nil {
return "", err
}
return base64.RawURLEncoding.EncodeToString(b), nil
}