| name | auth0 |
| description | [Applies to: **/*] Definitive guidelines for integrating Auth0 securely and efficiently, preventing common identity attacks, and leveraging modern authentication patterns. |
| source | cursor_mdc |
auth0 Best Practices
This guide outlines the definitive best practices for integrating Auth0 into our applications. Adhering to these standards is critical for maintaining a robust security posture against modern identity threats.
1. Prioritize Universal Login
Always centralize authentication flows using Auth0 Universal Login. This offloads complex security logic, ensures consistency, and leverages Auth0's built-in security features across all applications (web, mobile, AI agents).
❌ BAD: Implementing custom login forms or embedded login
This introduces significant security risks and maintenance overhead.
✅ GOOD: Redirecting to Universal Login with Auth0 SDKs
import { useAuth0 } from '@auth0/auth0-react';
function LoginButton() {
const { loginWithRedirect } = useAuth0();
const handleLogin = () => {
loginWithRedirect({
appState: { targetUrl: window.location.pathname },
authorizationParams: {
redirect_uri: window.location.origin + '/callback',
scope: 'openid profile email',
},
});
};
return <button onClick={handleLogin}>Log In</button>;
}
2. Enforce Authorization Code Flow with PKCE
For all public clients (SPAs, mobile apps, native desktop apps), the Authorization Code Flow with Proof Key for Code Exchange (PKCE) is the only acceptable grant type. This prevents authorization code injection attacks. Never use Implicit Grant or Resource Owner Password Grant (ROPG).
❌ BAD: Using Implicit Grant or ROPG
These flows are deprecated and highly vulnerable.
✅ GOOD: Authorization Code Flow with PKCE
Ensure your Auth0 application is configured for PKCE, and your SDK handles the code_challenge and code_verifier.
package main
import (
"context"
"log"
"net/http"
"github.com/auth0/go-auth0/v2/authentication"
"github.com/auth0/go-auth0/v2/authentication/oauth"
)
var authAPI *authentication.Authentication
func initAuthAPI() {
var err error
authAPI, err = authentication.New(
context.Background(),
"example.us.auth0.com",
authentication.WithClientID("YOUR_CLIENT_ID"),
authentication.WithClientSecret("YOUR_CLIENT_SECRET"),
)
if err != nil {
log.Fatalf("Failed to initialize Auth0 authentication API client: %+v", err)
}
}
func handleAuth0Callback(w http.ResponseWriter, r *http.Request) {
code := r.URL.Query().Get("code")
codeVerifier := r.Context().Value("code_verifier").(string)
tokenSet, err := authAPI.OAuth.LoginWithAuthCodeWithPKCE(r.Context(), oauth.LoginWithAuthCodeWithPKCERequest{
Code: code,
CodeVerifier: codeVerifier,
RedirectURI: "https://your-app.com/callback",
}, oauth.IDTokenValidationOptions{})
if err != nil {
log.Printf("Failed to exchange code for tokens: %v", err)
http.Error(w, "Authentication failed", http.StatusInternalServerError)
return
}
log.Printf("Successfully authenticated user: %s", tokenSet.IDToken)
http.Redirect(w, r, "/dashboard", http.StatusFound)