{"id":16750119,"url":"https://github.com/alexferl/echo-casbin","last_synced_at":"2025-10-26T17:06:44.825Z","repository":{"id":61839364,"uuid":"553966095","full_name":"alexferl/echo-casbin","owner":"alexferl","description":"Casbin middleware for the Echo framework.","archived":false,"fork":false,"pushed_at":"2024-02-06T19:57:58.000Z","size":37,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-22T16:48:52.627Z","etag":null,"topics":["casbin","echo","echo-casbin","echo-middleware","labstack-echo"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexferl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-19T03:24:13.000Z","updated_at":"2024-05-16T01:52:34.000Z","dependencies_parsed_at":"2024-06-19T05:21:31.224Z","dependency_job_id":null,"html_url":"https://github.com/alexferl/echo-casbin","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexferl%2Fecho-casbin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexferl%2Fecho-casbin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexferl%2Fecho-casbin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexferl%2Fecho-casbin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexferl","download_url":"https://codeload.github.com/alexferl/echo-casbin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243823332,"owners_count":20353652,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["casbin","echo","echo-casbin","echo-middleware","labstack-echo"],"created_at":"2024-10-13T02:27:08.354Z","updated_at":"2025-10-26T17:06:39.780Z","avatar_url":"https://github.com/alexferl.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# echo-casbin [![Go Report Card](https://goreportcard.com/badge/github.com/alexferl/echo-casbin)](https://goreportcard.com/report/github.com/alexferl/echo-casbin) [![codecov](https://codecov.io/gh/alexferl/echo-casbin/branch/master/graph/badge.svg)](https://codecov.io/gh/alexferl/echo-casbin)\n\nA [Casbin](https://casbin.io/) middleware for the [Echo](https://github.com/labstack/echo) framework.\n\n## Installing\n```shell\ngo get github.com/alexferl/echo-casbin\n```\n\n## Motivation\nYou might wonder why not use the Casbin middleware in the [echo-contrib](https://github.com/labstack/echo-contrib/tree/master/casbin) repo?\nThe main reason is that it doesn't provide any built-in methods for retrieving roles other than the default\nBasic Authorization header. You can pass your own function in place of it, but I wanted to have built-in methods\nthat I will use in most of my projects. You can still define your own function to retrieve roles, so it's still flexible.\n\n## Using\nYou need to have a model and policy before you can use the middleware. You can use the ones in [here](fixtures) to get\nstarted.\n\n### Code example\nThis example expects the roles to be passed in the `X-Roles` header. There is **no** validation done to make sure the\nclient doing the request is allowed to use these roles, this is beyond the scope of this middleware. A function can be\ndefined with the `RolesHeaderFunc` config to do the validation.\n\nThe default way the middleware gets the roles is from the key `roles` on the `echo.Context`. In a real application,\nanother middleware running before this one would validate the client's identity and set their roles on the context so\nthis middleware can access them.\n\n```go\npackage main\n\nimport (\n\t\"net/http\"\n\n\tmw \"github.com/alexferl/echo-casbin\"\n\t\"github.com/casbin/casbin/v2\"\n\t\"github.com/labstack/echo/v4\"\n)\n\nfunc main() {\n\te := echo.New()\n\n\te.GET(\"/\", func(c echo.Context) error {\n\t\treturn c.JSON(http.StatusOK, \"ok\")\n\t})\n\n\te.GET(\"/user\", func(c echo.Context) error {\n\t\treturn c.JSON(http.StatusOK, \"user\")\n\t})\n\n\tenforcer, err := casbin.NewEnforcer(\"/path/to/model.conf\", \"/path/to/policy.csv\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tconfig := mw.Config{\n\t\tEnforcer:          enforcer,\n\t\tEnableRolesHeader: true,\n\t}\n\te.Use(mw.CasbinWithConfig(config))\n\n\te.Logger.Fatal(e.Start(\"localhost:1323\"))\n}\n```\n\nMaking a request to non-protected endpoint:\n```shell\ncurl http://localhost:1323\n\"ok\"\n```\n\nMaking a request to a protected endpoint:\n```shell\ncurl http://localhost:1323/user\n{\"message\":\"Access to this resource has been restricted\"}\n```\n\nMaking a request to a protected endpoint with the right role:\n```shell\ncurl http://localhost:1323/user -H 'X-Roles: user'\n\"user\"\n```\n\n### Configuration\n```go\ntype Config struct {\n\t// Skipper defines a function to skip middleware.\n\tSkipper middleware.Skipper\n\n\t// Enforce defines the enforcer used for\n\t// authorization enforcement and policy management.\n\t// Required.\n\tEnforcer *casbin.Enforcer\n\n\t// ContextKey defines the key that will be used to\n\t// read the roles on the echo.Context for enforcing.\n\t// Optional. Defaults to \"roles\".\n\tContextKey string\n\n\t// DefaultRoles defines\n\t// Optional. Defaults to \"any\".\n\tDefaultRole string\n\n\t// EnableRolesHeader enables the RolesHeader.\n\t// Optional. Defaults to false.\n\tEnableRolesHeader bool\n\n\t// RolesHeader defines the header that will be used to\n\t// read in the roles if EnableRolesHeader is set to true.\n\t// Roles should be separated by commas. E.g. \"role1,role2\".\n\t// Optional. Defaults to false.\n\tRolesHeader string\n\n\t// RolesHeaderFunc defines the function that will validate that\n\t// a client is allowed to the use roles they passed via the RolesHeader.\n\t// The RolesHeader value will be passed unmodified, so you will need\n\t// to parse it in this function yourself. The DefaultRole will be passed\n\t// if the RolesHeader is empty. The roles that you want to have\n\t// enforced will need to be returned in a slice: []string{\"role1, \"role2\"}.\n\t// Optional.\n\tRolesHeaderFunc func(string) ([]string, error)\n\n\t// RolesFunc defines the function that will retrieve the roles\n\t// to be passed to the Enforcer.\n\t// Takes precedence over ContextKey and RolesHeader if they're defined.\n\t// Optional.\n\tRolesFunc func(echo.Context) ([]string, error)\n\n\t// ForbiddenMessage defines the message that will be\n\t// returned when authorization fails.\n\t// Optional. Defaults to \"Access to this resource has been restricted\".\n\tForbiddenMessage string\n\n\t// SuccessFunc defines the function that will run\n\t// when authorization succeeds.\n\t// Optional.\n\tSuccessFunc func(string, string, string)\n\n\t// FailureFunc defines the function that will run\n\t// when authorization fails.\n\t// Optional.\n\tFailureFunc func([]string, string, string)\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexferl%2Fecho-casbin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexferl%2Fecho-casbin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexferl%2Fecho-casbin/lists"}