{"id":21142619,"url":"https://github.com/klipitkas/tokenauth","last_synced_at":"2025-03-14T13:21:56.229Z","repository":{"id":48314787,"uuid":"297154773","full_name":"klipitkas/tokenauth","owner":"klipitkas","description":"API token authentication for go-fiber","archived":false,"fork":false,"pushed_at":"2023-06-14T14:53:58.000Z","size":23,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-21T07:11:20.386Z","etag":null,"topics":["api","authentication","fiber","go-fiber","golang","hacktoberfest","token"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/klipitkas.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":"2020-09-20T20:07:46.000Z","updated_at":"2021-02-20T08:48:09.000Z","dependencies_parsed_at":"2024-06-21T10:45:44.553Z","dependency_job_id":"d6c985b5-48e5-4270-8d57-c05bdfe43626","html_url":"https://github.com/klipitkas/tokenauth","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klipitkas%2Ftokenauth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klipitkas%2Ftokenauth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klipitkas%2Ftokenauth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klipitkas%2Ftokenauth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/klipitkas","download_url":"https://codeload.github.com/klipitkas/tokenauth/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243581113,"owners_count":20314176,"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":["api","authentication","fiber","go-fiber","golang","hacktoberfest","token"],"created_at":"2024-11-20T07:57:13.706Z","updated_at":"2025-03-14T13:21:56.209Z","avatar_url":"https://github.com/klipitkas.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Go Report Card](https://goreportcard.com/badge/github.com/klipitkas/tokenauth)](https://goreportcard.com/report/github.com/klipitkas/tokenauth)\n[![GitHub issues](https://img.shields.io/github/issues/klipitkas/tokenauth)](https://github.com/klipitkas/tokenauth/issues)\n[![GitHub license](https://img.shields.io/github/license/klipitkas/tokenauth)](https://github.com/klipitkas/tokenauth/blob/master/LICENSE)\n\n# 🔒 Token Authentication\n\nToken Authentication middleware for [Fiber](https://github.com/gofiber/fiber) that provides a basic token authentication.\n\n## 📝 Table of contents\n\n**Examples**\n\n- [In memory](#in-memory)\n- [Databases](#databases)\n  - [Postgres](#postgres)\n- [Redis](#redis)\n\n**Token Generation**\n\n- [Default](#default-token-generation)\n- [Custom](#custom-token-generation)\n\n---\n\n### IN MEMORY\n\nExample for in memory token storage:\n\n```go\npackage main\n\nimport (\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/klipitkas/tokenauth\"\n)\n\nvar Tokens = map[string]tokenauth.Claims{\n\t\"token\": {\"user\": \"john\", \"email\": \"john@example.com\", \"id\": \"42\"},\n}\n\nfunc main() {\n\tapp := fiber.New()\n\n\tapp.Use(tokenauth.New(tokenauth.Config{\n\t\tAuthorizer: func(s string) tokenauth.Claims {\n\t\t\tclaims, exist := Tokens[s]\n\t\t\tif !exist {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\treturn claims\n\t\t},\n\t}))\n\n\tapp.Get(\"/\", func(c *fiber.Ctx) error {\n\t\tclaims := c.Locals(\"claims\").(tokenauth.Claims)\n\t\treturn c.SendString(\"Hello, \" + claims[\"user\"] + \" 👋!\")\n\t})\n\n\t_ = app.Listen(\":3000\")\n}\n```\n\nTry to access the route without a token:\n\n```shell\n$ curl http://localhost:3000\nUnauthorized\n```\n\nTry to access the route after providing a token:\n\n```shell\n$ curl -H 'Authorization: Bearer token' http://localhost:3000\nHello, john 👋!\n```\n\n### DATABASES\n\n#### POSTGRES\n\nUse docker to launch a new ephemeral postgres database:\n\n```shell\n$ docker run -p 5432:5432 -e POSTGRES_PASSWORD=tokenauth -e POSTGRES_USER=tokenauth -e POSTGRES_DB=tokenauth -d postgres\n```\n\nTry the following example:\n\n```go\npackage main\n\nimport (\n\t\"database/sql\"\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/klipitkas/tokenauth\"\n\n\t_ \"github.com/lib/pq\"\n)\n\nconst (\n\thost   = \"localhost\"\n\tport   = 5432\n\tuser   = \"tokenauth\"\n\tpass   = \"tokenauth\"\n\tdbname = \"tokenauth\"\n)\n\nvar sqlMigration string = `\nDROP TABLE IF EXISTS user_tokens;\nDROP TABLE IF EXISTS users;\n\nCREATE TABLE users (\n\tid INT,\n\temail TEXT,\n\tPRIMARY KEY(id)\n);\n\nCREATE TABLE user_tokens (\n\tid INT,\n\tuser_id INT,\n\ttoken TEXT,\n\tPRIMARY KEY(id),\n\tUNIQUE(token),\n\tCONSTRAINT fk_customer FOREIGN KEY(user_id) REFERENCES users(id) ON DELETE CASCADE\n);`\n\nvar sqlSeeder string = `\n\tINSERT INTO users VALUES (1, 'john@example.com');\n\tINSERT INTO users VALUES (2, 'jim@example.com');\n\n\tINSERT INTO user_tokens VALUES (1, 1, 'token');\n\tINSERT INTO user_tokens VALUES (2, 2, 'fgu9KILmznhLtQgmr3');\n`\n\nfunc main() {\n\tapp := fiber.New()\n\n\t// Connect to the database.\n\tdb, err := dbConnect(host, user, pass, dbname, port)\n\tif err != nil {\n\t\tlog.Fatalf(\"Failed to connect to db: %v\", err)\n\t}\n\n\t// Run the migrations.\n\tif _, err = db.Exec(sqlMigration); err != nil {\n\t\tlog.Fatalf(\"Failed to run the migrations: %v\", err)\n\t}\n\n\t// Run the seeders.\n\tif _, err = db.Exec(sqlSeeder); err != nil {\n\t\tlog.Fatalf(\"Failed to run the migrations: %v\", err)\n\t}\n\n\t// Use our custom authorizer to verify tokens from the DB.\n\tapp.Use(tokenauth.New(tokenauth.Config{Authorizer: dbTokenAuthorizer}))\n\n\t// Our protected route\n\tapp.Get(\"/\", func(c *fiber.Ctx) error {\n\t\tclaims := c.Locals(\"claims\").(tokenauth.Claims)\n\t\treturn c.SendString(\"Hello, user with ID: \" + claims[\"user_id\"] + \" 👋!\")\n\t})\n\n\t_ = app.Listen(\":3000\")\n\n\tdefer db.Close()\n}\n\nfunc dbConnect(host, user, pass, dbname string, port int) (*sql.DB, error) {\n\tconnStr := fmt.Sprintf(\"host=%s port=%d user=%s \"+\n\t\t\"password=%s dbname=%s sslmode=disable\",\n\t\thost, port, user, pass, dbname)\n\n\t// Validate the connection arguments\n\tdb, err := sql.Open(\"postgres\", connStr)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"connect to db: %v\", err)\n\t}\n\n\tif err = db.Ping(); err != nil {\n\t\treturn nil, fmt.Errorf(\"ping the db: %v\", err)\n\t}\n\n\treturn db, nil\n}\n\nfunc dbTokenAuthorizer(token string) tokenauth.Claims {\n\t// Connect to the database.\n\tdb, err := dbConnect(host, user, pass, dbname, port)\n\tif err != nil {\n\t\tfmt.Printf(\"connect to db: %v\", err)\n\t\treturn nil\n\t}\n\tdefer db.Close()\n\n\t// Get the user id if the token is valid.\n\t// You can do more things here, such as JOIN statements with the users\n\t// table and get more information for the user.\n\trows, err := db.Query(\"SELECT user_id FROM user_tokens WHERE token = $1\", token)\n\tif err != nil || rows.Err() != nil {\n\t\tfmt.Printf(\"run query for tokens: %v\", err)\n\t\treturn nil\n\t}\n\n\t// Set a default empty user ID.\n\tuserID := \"\"\n\tfor rows.Next() {\n\t\tif err := rows.Scan(\u0026userID); err != nil {\n\t\t\tfmt.Printf(\"get token rows: %v\", err)\n\t\t\treturn nil\n\t\t}\n\t}\n\n\t// Check if we got a valid (non-zero length) user id.\n\tif len(userID) \u003e 0 {\n\t\treturn tokenauth.Claims{\"user_id\": userID}\n\t}\n\n\treturn nil\n}\n```\n\nTry to access the route without a token:\n\n```shell\n$ curl http://localhost:3000\nUnauthorized\n```\n\nTry to access the route after providing a token:\n\n```shell\n$ curl -H 'Authorization: Bearer token' http://localhost:3000\nHello, user with ID: 1 👋!\n```\n\n```shell\n$ curl -H 'Authorization: Bearer fgu9KILmznhLtQgmr3' http://localhost:3000\nHello, user with ID: 2 👋!\n```\n\n### REDIS\n\nUse docker to launch a new ephemeral redis instance:\n\n```shell\n$ docker run -p 6379:6379 --name redis -d redis\n```\n\nTry the following example:\n\n```go\npackage main\n\nimport (\n\t\"github.com/gofiber/fiber/v2\"\n\t\"github.com/klipitkas/tokenauth\"\n\n\t\"context\"\n\n\t\"github.com/go-redis/redis/v8\"\n)\n\nfunc main() {\n\tapp := fiber.New()\n\n\t// Use our custom authorizer to verify tokens from Redis.\n\tapp.Use(tokenauth.New(tokenauth.Config{Authorizer: redisTokenAuthorizer}))\n\n\t// Our protected route\n\tapp.Get(\"/\", func(c *fiber.Ctx) error {\n\t\tclaims := c.Locals(\"claims\").(tokenauth.Claims)\n\t\treturn c.SendString(\"Hello, user with details: \" + claims[\"user\"] + \" !👋\")\n\t})\n\n\t_ = app.Listen(\":3000\")\n}\n\nfunc redisTokenAuthorizer(token string) tokenauth.Claims {\n\t// Create a new redis client and connect to Redis instance.\n\tredis := redis.NewClient(\u0026redis.Options{\n\t\tAddr:     \"localhost:6379\",\n\t\tPassword: \"\",\n\t\tDB:       0,\n\t})\n\tdefer redis.Close()\n\n\t// Test if connection to Redis works.\n\tif _, err := redis.Ping(context.Background()).Result(); err != nil {\n\t\treturn nil\n\t}\n\n\t// Fetch the user details using the token as a key.\n\tuser, err := redis.Get(context.Background(), token).Result()\n\tif err != nil {\n\t\treturn nil\n\t}\n\n\tif len(user) \u003e 0 {\n\t\treturn tokenauth.Claims{\"user\": user}\n\t}\n\n\treturn nil\n}\n```\n\nNow you can create a new token using `redis-cli`:\n\n```shell\n$  docker exec -it redis redis-cli\n127.0.0.1:6379\u003e set token test\nOK\n```\n\nTry to access the route without a token:\n\n```shell\n$ curl http://localhost:3000\nUnauthorized\n```\n\nTry to access the route after providing a token:\n\n```shell\n$ curl -H 'Authorization: Bearer token' http://localhost:3000\nHello, user with details: test 👋!\n```\n\n### Default Token Generation\n\nTo generate a new token with the default config:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/klipitkas/tokenauth\"\n)\n\nfunc main() {\n\ttoken, err := tokenauth.NewToken(tokenauth.TokenConfig{})\n\tif err != nil {\n\t\tlog.Fatalf(\"Token generation failed: %v\", err)\n\t}\n\tfmt.Printf(\"Token: %s\", token)\n}\n```\n\nYou can specify the following parameters as the token configuration:\n\n```go\n// TokenConfig is the struct that contains the config\n// for token generation.\ntype TokenConfig struct {\n\t// Alphabet contains the characters that can be used as parts of the token.\n\tAlphabet string\n\t// Length is the length of the token to generate.\n\tLength int\n\t// Generator is the function that can be used to generate tokens.\n\tGenerator func(int, string) (string, error)\n}\n```\n\n### Custom Token Generation\n\nIf you want to use a custom function to generate a token:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/klipitkas/tokenauth\"\n)\n\nfunc main() {\n\ttoken, err := tokenauth.NewToken(tokenauth.TokenConfig{\n\t\tGenerator: ultraSecureTokenGenerator,\n\t})\n\tif err != nil {\n\t\tlog.Fatalf(\"Token generation failed: %v\", err)\n\t}\n\tfmt.Printf(\"Token: %s\", token)\n}\n\nfunc ultraSecureTokenGenerator(length int, alphabet string) (string, error) {\n\treturn \"token\", nil\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklipitkas%2Ftokenauth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fklipitkas%2Ftokenauth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklipitkas%2Ftokenauth/lists"}