RESTful adapter for Casbin on Echo web framework. Simplify your authorization with powerful role-based access control.
- π Easy Integration - Seamlessly integrate with Echo applications
- π RESTful Authorization - Built for RESTful API security
- π‘οΈ Token-Based Authentication - JWT token support out of the box
- π Flexible Data Source - Define your own data source interface
- β‘ High Performance - Minimal overhead middleware
- π― Role-Based Access Control - Fine-grained RBAC support
go get github.com/prongbang/casbinrestImplement the DataSource interface to fetch roles based on tokens:
type redisDataSource struct {
// Add your Redis client here
}
func NewRedisDataSource() casbinrest.DataSource {
return &redisDataSource{}
}
func (r *redisDataSource) GetRoleByToken(reqToken string) string {
// Implement your logic to fetch role from Redis
// This is just a simple example
if reqToken == "valid-admin-token" {
return "admin"
}
return "anonymous"
}package main
import (
"github.com/labstack/echo/v4"
"github.com/prongbang/casbinrest"
"github.com/casbin/casbin/v2"
"net/http"
)
func main() {
// Initialize data source
redisSource := NewRedisDataSource()
// Setup Casbin enforcer
ce, _ := casbin.NewEnforcer("auth_model.conf", "policy.csv")
// Create Echo instance
e := echo.New()
// Apply middleware
e.Use(casbinrest.Middleware(ce, redisSource))
// Routes
e.GET("/", func(c echo.Context) error {
return c.JSON(http.StatusOK, "Welcome!")
})
e.GET("/admin", func(c echo.Context) error {
return c.JSON(http.StatusOK, "Admin area")
})
e.GET("/login", func(c echo.Context) error {
return c.JSON(http.StatusOK, "Login page")
})
e.Logger.Fatal(e.Start(":1323"))
}Create auth_model.conf:
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)Create policy.csv:
p, admin, /, GET
p, admin, /admin, GET
p, anonymous, /login, GET
p, anonymous, /, GET# Access public endpoint
curl http://localhost:1323/login
# Access protected endpoint without token
curl http://localhost:1323/admin
# Returns 403 Forbidden
# Access protected endpoint with valid token
curl -H "Authorization: Bearer your-admin-token" http://localhost:1323/admin
# Returns 200 OKImplement different data sources for various backends:
// MySQL Data Source
type mysqlDataSource struct {
db *sql.DB
}
func (m *mysqlDataSource) GetRoleByToken(token string) string {
var role string
err := m.db.QueryRow("SELECT role FROM users WHERE token = ?", token).Scan(&role)
if err != nil {
return "anonymous"
}
return role
}
// MongoDB Data Source
type mongoDataSource struct {
collection *mongo.Collection
}
func (m *mongoDataSource) GetRoleByToken(token string) string {
var result struct {
Role string `bson:"role"`
}
err := m.collection.FindOne(context.Background(), bson.M{"token": token}).Decode(&result)
if err != nil {
return "anonymous"
}
return result.Role
}- Use Secure Tokens - Always use properly signed JWT tokens
- HTTPS Only - Ensure your API is served over HTTPS
- Token Expiration - Implement token expiration mechanisms
- Regular Policy Updates - Keep your policies up to date
- Audit Logging - Log authorization decisions for security audits
- The middleware has minimal overhead
- Policy matching is efficient with Casbin's optimized algorithms
- Consider caching role lookups for high-traffic applications
- Use appropriate indexes in your data source
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
If you find this package helpful, please consider supporting it:
- Casbin - Authorization library
- Echo - High performance Go web framework
- JWT-Go - JWT implementation for Go
