{"id":21834279,"url":"https://github.com/ennaque/go-gin-jwt","last_synced_at":"2025-04-14T08:37:40.608Z","repository":{"id":57632077,"uuid":"412960538","full_name":"ennaque/go-gin-jwt","owner":"ennaque","description":"jwt package for gin go applications","archived":false,"fork":false,"pushed_at":"2022-02-06T01:57:08.000Z","size":159,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-27T22:11:07.527Z","etag":null,"topics":["gin","gin-jwt","go","jwt","jwt-authentication","jwt-middleware"],"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/ennaque.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}},"created_at":"2021-10-03T02:50:44.000Z","updated_at":"2024-04-25T12:49:50.000Z","dependencies_parsed_at":"2022-08-31T13:20:55.239Z","dependency_job_id":null,"html_url":"https://github.com/ennaque/go-gin-jwt","commit_stats":null,"previous_names":["ennaque/gin-jwt","ennaque/gwt"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennaque%2Fgo-gin-jwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennaque%2Fgo-gin-jwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennaque%2Fgo-gin-jwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ennaque%2Fgo-gin-jwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ennaque","download_url":"https://codeload.github.com/ennaque/go-gin-jwt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248847027,"owners_count":21171077,"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":["gin","gin-jwt","go","jwt","jwt-authentication","jwt-middleware"],"created_at":"2024-11-27T20:09:44.472Z","updated_at":"2025-04-14T08:37:40.585Z","avatar_url":"https://github.com/ennaque.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gin-jwt ![tests](https://github.com/ennaque/go-gin-jwt/workflows/tests/badge.svg) [![codecov](https://codecov.io/gh/ennaque/go-gin-jwt/branch/master/graph/badge.svg?token=WZMWD36EKQ)](https://codecov.io/gh/ennaque/go-gin-jwt) [![codebeat badge](https://codebeat.co/badges/e1ea8bb5-f305-4394-bab2-308efe3f718d)](https://codebeat.co/projects/github-com-ennaque-go-gin-jwt-master)\njwt package for gin go applications\n\n# Usage\n\nDownload using [go module](https://blog.golang.org/using-go-modules):\n\n```sh\ngo get github.com/ennaque/go-gin-jwt@v1.0.5\n```\n\nImport it in your code:\n\n```go\nimport gwt \"github.com/ennaque/go-gin-jwt\"\nimport gwtstorage \"github.com/ennaque/go-gin-jwt/storage\"\n```\n\n# Example\n\n```go\npackage main\n\nimport (\n\tgwt \"github.com/ennaque/go-gin-jwt\"\n\tgwtstorage \"github.com/ennaque/go-gin-jwt/storage\"\n\t\"github.com/go-redis/redis/v8\"\n\t\"gorm.io/driver/postgres\"\n\t\"gorm.io/gorm\"\n)\n\nfunc main() {\n\trouter := gin.Default()\n\n\t// GetDBConnectionData() - user func, must return dns string\n\t// postgres is not required, other drivers can be used here\n\tdb, err := gorm.Open(postgres.Open(GetDBConnectionData()))\n\tif err != nil {\n\t\tpanic(\"db con failed\")\n\t}\n\n\t// init gorm storage\n\tgs, err := gwtstorage.InitGormStorage(db, \"jwt1234_\")\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\t// init redis storage\n\t// GetRedisOptions() - user func, must return *redis.Options\n\trs := gwtstorage.InitRedisStorage(redis.NewClient(GetRedisOptions()))\n\n\tauth, _ := gwt.Init(gwt.Settings{\n\t\tAuthenticator: func(c *gin.Context) (string, error) { // required\n\t\t\t// LoginCredentials - your login credentials model, can be differ\n\t\t\tvar loginCredentials LoginCredentials\n\t\t\tif err := c.ShouldBind(\u0026loginCredentials); err != nil {\n\t\t\t\treturn \"\", errors.New(\"bad request\")\n\t\t\t}\n\t\t\t// GetUserByCredentials - user func, must return user model\n\t\t\tuser, err := GetUserByCredentials(\u0026loginCredentials)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", errors.New(\"unauthorized\")\n\t\t\t}\n\t\t\treturn user.GetId(), nil\n\t\t},\n\t\tAccessSecretKey:  []byte(\"access_super_secret\"), // required\n\t\tRefreshSecretKey: []byte(\"refresh_super_secret\"), // optional, default - AccessSecretKey\n\t\tStorage:          gs, // required, use gorm or redis storage\n\t\t// Storage: rs,\n\t\tGetUserFunc: func(userId string) (interface{}, error) { // required\n\t\t\treturn GetUserById(userId)\n\t\t},\n\t\tAccessLifetime:  time.Minute * 15, // optional, default - time.Minute * 15\n\t\tRefreshLifetime: time.Hour * 24, // optional, default - time.Hour * 24\n\t\tSigningMethod:   \"HS256\", // optional, default - HS256\n\t\tAuthHeadName:    \"Bearer\", // optional, default - Bearer\n\t\tAdditionalAuthHeader: \"x-auth-token\", // optional, can be used to avoid safari redirect bug\n\t})\n\n\ta := router.Group(\"auth\")\n\t{\n\t\ta.POST(\"/logout\", auth.Handler.GetLogoutHandler())\n\t\ta.POST(\"/login\", auth.Handler.GetLoginHandler())\n\t\ta.POST(\"/refresh\", auth.Handler.GetRefreshHandler())\n\t\ta.POST(\"/force-logout\", auth.Handler.GetForceLogoutHandler())\n\t}\n\n\trouter.Group(\"/api\").Use(auth.Middleware.GetAuthMiddleware()).GET(\"/get-user-id\", func(c *gin.Context) {\n\t\tuser, _ := c.Get(\"user\")\n\t\tc.JSON(http.StatusOK, gin.H{\n\t\t\t\"userId\": user.(*models.User).ID,\n\t\t})\n\t})\n\n\terr := router.Run(\":8000\")\n\tif err != nil {\n\t\tpanic(\"err\")\n\t}\n}\n```\n\n## Get tokens\n\n```sh\ncurl -X POST -d \"username=\u003cuser_name\u003e\u0026password=\u003cpassword\u003e\" http://localhost:8000/auth/login\n```\nusername and password params may differ depending on your login credentials\n\nResponse `200 OK`:\n```sh\n{\n    \"access_expire\": \"1633653988\",\n    \"access_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6IjlkODFmNjRkLWY0ZWYtNDA2NC04YTY3LTRjNjMzY2MxNjExOCIsImV4cCI6MTYzMzY1Mzk4OCwicmVmcmVzaF91dWlkIjoiOTU3NWU5ZDEtNWFjOS00YmIzLTkwOGItODA3MmJkNDdmOTM2IiwidXNlcl9pZCI6IjI5In0.0CfHPjkVFiQixa4SdE5EUhu23imNri02QMFsDDXJHzg\",\n    \"refresh_expire\": \"1633739788\",\n    \"refresh_token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6IjlkODFmNjRkLWY0ZWYtNDA2NC04YTY3LTRjNjMzY2MxNjExOCIsImV4cCI6MTYzMzczOTc4OCwicmVmcmVzaF91dWlkIjoiOTU3NWU5ZDEtNWFjOS00YmIzLTkwOGItODA3MmJkNDdmOTM2IiwidXNlcl9pZCI6IjI5In0.UvPTvVaNkAgFVTrAEoaUK1n4iIYFGh1yNqPzzNbtUUM\"\n}\n```\n\n## Refresh token\n\n```sh\ncurl -X POST -d \"refresh_token=\u003crefresh_token\u003e\" http://localhost:8000/auth/refresh\n```\n\nResponse `200 OK`:\n```sh\n{\n    \"access_expire\":\"1633659261\",\n    \"access_token\":\"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6ImJiNjBhYzlmLTQ4ZGEtNDlhZC04NTM1LTU5MTJhY2MwZDIwNyIsImV4cCI6MTYzMzY1OTI2MSwicmVmcmVza\nF91dWlkIjoiNDkxMWYxZjUtYjk5Ni00ZTEwLWE4NGEtNDg3NGVmNjMzZDc4IiwidXNlcl9pZCI6IjI5In0.tupNFRnANQmOScjWzlnWXzncX0Kxs7M40rsbFs0Vpg-70Ucc7R7vX2e7uAFf1fiAMODfGS5d3PRK3Nwk4RoPzg\",\n    \"refresh_expire\":\"1633831941\",\n    \"refresh_token\":\"eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3NfdXVpZCI6ImJiNjBhYzlmLTQ4ZGEtNDlhZC04NTM1LTU5MTJhY2MwZDIwNyIsImV4cCI6MTYzMzgzMTk0MSwicmVmcmVz\naF91dWlkIjoiNDkxMWYxZjUtYjk5Ni00ZTEwLWE4NGEtNDg3NGVmNjMzZDc4IiwidXNlcl9pZCI6IjI5In0.lj2nS6-M4GT-T9PHj9ijNY4g6h5hyP0xdVTHCw1M-07aL4zp7HpFrXFrT-V6RWpofaGvM79o64f8WECEqRPjig\"\n}\n```\n\n## Logout\n\n```sh\ncurl -X POST -H \"Authorization: Bearer \u003caccess_token\u003e\" http://localhost:8000/auth/logout\n```\n\nResponse `200 OK`:\n```sh\n{}\n```\n\n## Force logout user\n\nThis endpoint should be used only by authorized user.\n\n```sh\ncurl -X POST -H \"Authorization: Bearer \u003caccess_token\u003e\" -d \"user_id=\u003cuser_id_to_logout\u003e\" http://localhost:8000/auth/force-logout\n```\nResponse `200 OK`:\n```sh\n{}\n```\nAdditionaly there is a public method ```gwt.Service.ForceLogoutUser(userId)```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fennaque%2Fgo-gin-jwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fennaque%2Fgo-gin-jwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fennaque%2Fgo-gin-jwt/lists"}