Your cart is currently empty!
Understanding JWT Authentication with PostgREST
TLDR: Here is the example you can spin up in docker to test: https://github.com/jcianci12/jwt-postgrest-example
Introduction
PostgREST is a powerful tool that automatically creates RESTful APIs from PostgreSQL databases. One of its key features is built-in JWT (JSON Web Token) authentication support. This article explains how PostgREST expects and handles JWT tokens, and how to properly implement JWT authentication in your application.
JWT Structure Expected by PostgREST
PostgREST expects JWT tokens to follow a specific structure. The token should contain claims that PostgREST can use for authentication and authorization. Here’s the expected structure:
{
"role": "authenticated", // The database role to use
"iss": "your-issuer", // Token issuer
"sub": "user123", // Subject (usually user ID)
"exp": 1516239022, // Expiration timestamp
"iat": 1516235422, // Issued at timestamp
"email": "user@example.com" // Optional custom claims
}
Key JWT Claims
- role: The database role to use for the request
- Common values: “authenticated”, “anon”, “service_role”
- Must match a role in your PostgreSQL database
- iss (Issuer): Who created the token
- Should match your JWT issuer configuration
- sub (Subject): The user identifier
- Usually the user’s ID or unique identifier
- exp (Expiration): When the token expires
- Unix timestamp in seconds
- iat (Issued At): When the token was created
- Unix timestamp in seconds
How to Pass the JWT
HTTP Header
PostgREST expects the JWT token in the Authorization header:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Example Implementation
Here’s how you might implement this in your application:
// Example TypeScript/JavaScript code
const createAuthHeader = (token: string) => {
return {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
};
// Using the header
const fetchData = async () => {
const response = await fetch('https://your-api.example.com/table', {
headers: createAuthHeader(jwtToken)
});
return response.json();
};
PostgREST Configuration
In your PostgREST configuration, you need to specify:
- JWT secret for verification
- JWT issuer
- JWT audience (optional)
Example configuration:
# postgrest.conf
jwt-secret = "your-secret-key"
jwt-aud = "your-audience"
jwt-iss = "your-issuer"
Row Level Security (RLS)
PostgREST works seamlessly with PostgreSQL’s Row Level Security (RLS). The JWT claims can be used in RLS policies:
-- Example RLS policy using JWT claims
CREATE POLICY user_access ON your_table
FOR ALL
USING (
auth.uid() = user_id -- auth.uid() gets the 'sub' claim
);
Common Pitfalls
- Incorrect Role: Ensure the role in the JWT matches a database role
- Missing Claims: Required claims must be present
- Expired Tokens: Check token expiration before sending
- Invalid Secret: JWT secret must match PostgREST configuration
Best Practices
- Token Expiration: Set reasonable expiration times
- Secure Storage: Store tokens securely (e.g., HttpOnly cookies)
- Error Handling: Implement proper error handling for invalid tokens
- Regular Rotation: Implement token rotation for security
- Claims Minimization: Only include necessary claims
Testing JWT Authentication
You can test your JWT implementation using tools like curl:
curl -X GET 'https://your-api.example.com/table' \
-H "Authorization: Bearer your.jwt.token"
Conclusion
Understanding how PostgREST handles JWT authentication is crucial for building secure and efficient APIs. By following these guidelines and best practices, you can implement robust authentication in your PostgREST-based applications.
Remember to:
- Structure your JWT claims correctly
- Configure PostgREST properly
- Implement proper security measures
- Test thoroughly
- Follow best practices for token management
by
Tags:
Leave a Reply