AuthAction is a powerful authentication and authorization platform that offers a range of features, including support for single-page applications (SPA) and machine-to-machine (M2M) applications. It provides an easy-to-use interface for managing users, roles, and organizations, and supports OAuth2, social logins and passkey authentication. Best of all, AuthAction is scalable, allowing up to 1 Million monthly active users for free. Whether you're developing an app for a startup or a large enterprise, AuthAction provides a flexible and secure solution for your authentication needs.
In this blog, we'll explore how to authorise Go APIs using AuthAction.
Prerequisites
Before you begin, ensure you have:
- Go 1.21 or later: Download from golang.org
- AuthAction Account: You'll need your AuthAction tenant domain and API identifier
Configuration
1. Install Required Packages
go get -u github.com/golang-jwt/jwt/v5
go get -u github.com/lestrrat-go/jwx/v2/jwk
go get -u github.com/gin-gonic/gin
2. Configure AuthAction Settings
Create a .env
file in your project root:
AUTHACTION_DOMAIN=your-authaction-tenant-domain
AUTHACTION_AUDIENCE=your-authaction-api-identifier
3. Implement JWT Middleware
Create a middleware file middleware/auth.go
:
type JWKSMiddleware struct {
JWKSUri string
Issuer string
Audience string
Cache *jwk.Cache
}
func NewJWKSMiddleware(jwksUri, issuer, audience string) (*JWKSMiddleware, error) {
cache := jwk.NewCache(context.Background())
return &JWKSMiddleware{
JWKSUri: jwksUri,
Issuer: issuer,
Audience: audience,
Cache: cache,
}, nil
}
func (m *JWKSMiddleware) ValidateToken() gin.HandlerFunc {
return func(c *gin.Context) {
// Get token from Authorization header
tokenString := strings.Split(c.GetHeader("Authorization"), " ")[1]
// Fetch JWKS from AuthAction with caching
keySet, _ := m.Cache.Get(context.Background(), m.JWKSUri)
// Parse and validate token
token, _ := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
kid := token.Header["kid"].(string)
key, _ := keySet.LookupKeyID(kid)
var rawkey interface{}
key.Raw(&rawkey)
return rawkey, nil
})
// Validate claims
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
if aud, ok := claims["aud"].(string); ok && aud == m.Audience {
c.Set("claims", claims)
c.Next()
return
}
}
c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"})
c.Abort()
}
}
Usage
1. Create Your API
Create your main API file main.go
:
func main() {
// Load environment variables
domain := os.Getenv("AUTHACTION_DOMAIN")
audience := os.Getenv("AUTHACTION_AUDIENCE")
// Construct JWKS URI and issuer
jwksUri := fmt.Sprintf("https://%s/.well-known/jwks.json", domain)
issuer := fmt.Sprintf("https://%s/", domain)
// Initialize middleware
authMiddleware, _ := middleware.NewJWKSMiddleware(jwksUri, issuer, audience)
r := gin.Default()
// Public endpoint
r.GET("/health", func(c *gin.Context) {
c.JSON(200, gin.H{"status": "healthy"})
})
// Protected endpoint
protected := r.Group("/api")
protected.Use(authMiddleware.ValidateToken())
{
protected.GET("/protected", func(c *gin.Context) {
claims, _ := c.Get("claims")
c.JSON(200, gin.H{
"message": "Protected endpoint",
"claims": claims,
})
})
}
r.Run(":8080")
}
2. Testing the API
- Obtain an Access Token:
curl --request POST \
--url https://your-authaction-tenant-domain/oauth2/m2m/token \
--header 'content-type: application/json' \
--data '{
"client_id": "your-authaction-m2m-app-clientid",
"client_secret": "your-authaction-m2m-app-client-secret",
"audience": "your-authaction-api-identifier",
"grant_type": "client_credentials"
}'
- Call Protected Endpoints:
curl --request GET \
--url http://localhost:8080/api/protected \
--header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Security Features
The implementation includes:
- JWT token validation using AuthAction's JWKS endpoint
- Automatic JWKS caching with periodic refresh
- RS256 algorithm for token signing
- Secure configuration management using environment variables
- HTTPS support in production
Common Issues
Invalid Token Errors
- Ensure your token is signed with RS256 algorithm
- Verify the token contains correct issuer and audience claims
- Check that environment variables are correctly set
Public Key Fetching Errors
- Verify your application can reach AuthAction's JWKS endpoint
- The JWKS URI should be:
https://your-authaction-tenant-domain/.well-known/jwks.json
Unauthorized Access
If requests to protected endpoints fail, check:
- The JWT token is included in the
Authorization
header - The token is valid and not expired
- The token's audience matches your API identifier
- The token's issuer matches your AuthAction domain
Conclusion
Integrating authorization into a Go API application using AuthAction is a straightforward process. This example helps streamline the setup, offering developers a robust foundation to build secure applications with minimal effort.
If you run into any issues, double-check your configurations to ensure everything is set up correctly. Happy coding!
Feel free to leave your thoughts and questions in the comments below!
Top comments (0)