{"id":13778683,"url":"https://github.com/nickgnd/hanami-jwt-example","last_synced_at":"2025-09-29T18:28:53.706Z","repository":{"id":84792003,"uuid":"84372369","full_name":"nickgnd/hanami-jwt-example","owner":"nickgnd","description":"A JSON API web application built with Hanami","archived":false,"fork":false,"pushed_at":"2018-10-17T16:07:27.000Z","size":57,"stargazers_count":31,"open_issues_count":4,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-02T03:12:03.924Z","etag":null,"topics":["cors-request","hanami","hanami-application","json-api","jwt-authentication","ruby","warden"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/nickgnd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-03-08T22:31:36.000Z","updated_at":"2022-11-27T05:05:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"4176e22a-08ae-4455-8030-60b1aa553cc8","html_url":"https://github.com/nickgnd/hanami-jwt-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickgnd%2Fhanami-jwt-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickgnd%2Fhanami-jwt-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickgnd%2Fhanami-jwt-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickgnd%2Fhanami-jwt-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickgnd","download_url":"https://codeload.github.com/nickgnd/hanami-jwt-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225048980,"owners_count":17412903,"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":["cors-request","hanami","hanami-application","json-api","jwt-authentication","ruby","warden"],"created_at":"2024-08-03T18:00:56.212Z","updated_at":"2025-09-29T18:28:48.664Z","avatar_url":"https://github.com/nickgnd.png","language":"Ruby","readme":"## JSON API with Hanami 🌸\n\nThe goal of this project is to provide an example of a JSON API web application built with [Hanami](http://hanamirb.org/) that exposes JWT-protected enpoints.\n\nMain features:\n\n- return a JSON representation of resources\n- store encrypted password in the db with [BCrypt](https://github.com/codahale/bcrypt-ruby)\n- implement a token based authentication strategy using [Warden Middleware](https://github.com/hassox/warden) and [JWT gem](https://github.com/jwt/ruby-jwt)\n- handle [preflight CORS requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)\n- use [Hanami framework](http://hanamirb.org/)\n\nDeveloped and tested with:\n\n- Ruby v2.3.1\n- Hanami v1.0\n\n## Try it yourself\n\n```bash\ngit clone https://github.com/nickgnd/hanami-jwt-example\ncd hanami-jwt-example\nbundle install\n```\n\nthen edit `.env.*` files to fit your environment and create the development and test databases\n\n```bash\nbundle exec hanami db create\nbundle exec hanami db migrate\nHANAMI_ENV=test bundle exec db create\nHANAMI_ENV=test bundle exec hanami db migrate\n```\n\nfinally, run tests to check if everything is ok\n\n```bash\nrake test\n```\n\nThe web application exposes an API which allows authenticated users to retrieve a collection of items.\nThe requests to this endpoint will be authenticated through a token based authentication strategy, passing a custom header `Authorization` containing the user's JWT.\n\n\nLet's start.\n\n```bash\nbundle exec hanami server\n```\n\nBy default it launches the development server at `http://localhost:2300`\n\n1) **Before we need to register a new user**\n\nTo do this, we have to make a `POST` request against `/registration` endpoint passing the required informations in the payload.\n\n_request_:`POST /registration`\n\n_payload_:\n\n```bash\n{ user: { email: \"hanami@exmaple.com\", password: \"cherryblossom\", password_confirmation: \"cherryblossom\" } }\n```\n\n_with curl_:\n```bash\ncurl -X POST -H \"Accept: application/json\" -H \"Content-Type: application/json\" -d '{ \"user\": { \"email\": \"hanami@exmaple.com\", \"password\": \"cherryblossom\", \"password_confirmation\": \"cherryblossom\" } }' \"http://localhost:2300/registration\"\n```\n\n2) **Retrive user's jwt**\n\nFor retrieving the JWT, we have to make a `POST` request to `/sessions` path passing user's email and password in the payload.\n\n_request_: `POST /sessions`\n\n_payload_:\n```bash\n{ user: { email: \"hanami@exmaple.com\", password: \"cherryblossom\" } }\n```\n\nThe response body will contain the JWT under the key `auth_token`, save it for the next step (retrieving item collections).\n\n_with curl_:\n```bash\ncurl -X POST -H \"Content-Type: application/json\" -H \"Accept: application/json\" -d '{ \"user\": { \"email\": \"hanami@exmaple.com\", \"password\": \"cherryblossom\" } }' \"http://localhost:2300/sessions\"\n```\n\nResponse example:\n\n```bash\n{\"auth_token\":\"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxNCwiaXNzIjoiaHR0cDovL2ludmVudG9yeS5jb20iLCJleHAiOjE0ODkwNDUxNDB9.RI2F5-6rsIU02yXa158iocRP2qKQoR-mi8jbsRM0mDo\"}\n```\n\n3) **Retrieving items**\n\nFinally, for retrieving the items we have to make a `GET` request against `/items` endpoint including the user's jwt in the headers.\n\n_request_: `GET /items`\n\n_headers_:\n`\"Authentication\": \"Bearer \u003cYOUR_JWT\u003e\"`\n\n_with curl_:\n```bash\ncurl -X GET -H \"Content-Type: application/json\" -H \"Accept: application/json\" -H \"Authorization: Bearer \u003cYOUR_JWT\u003e\" \"http://localhost:2300/items\"\n```\n\nThe response body will be an empty array because there are not items in the database, let's create a new one through the Hanami console:\n\n```bash\nbundle exec hanami console\n```\n\n```bash\nitem = Item.new(code: 'alfa', available: true)\n=\u003e #\u003cItem:0x007fa66b2da7d0 @attributes={:code=\u003e\"alfa\", :available=\u003etrue}\u003e\n\nItemRepository.new.create(item)\n=\u003e #\u003cItem:0x007fa66e040e18 @attributes={:id=\u003e1, :code=\u003e\"alfa\", :available=\u003etrue, :created_at=\u003e2017-03-08 23:00:11 UTC, :updated_at=\u003e2017-03-08 23:00:11 UTC}\u003e\n```\n\nNow the next request will return the item just created\n\n```bash\n[\n  { \"id\":1,\"code\":\"alfa\",\"available\":true,\"created_at\":\"2017-03-08 23:00:11 UTC\",\"updated_at\":\"2017-03-08 23:00:11 UTC\" }\n]\n```\n\net voilà!\n\n## Contributing\n\nFeel free to submit issues for questions, bugs and enhancements.\n\nand as usual...\n\n1. Fork the repo\n2. Create your feature branch\n3. Commit changes to your own branch\n4. Push it\n5. Submit a Pull Request\n\n## Credits\n\nThis project is inspired by this tutorial [Using rails-api to build an authenticated JSON API with warden](http://lucatironi.net/tutorial/2015/08/23/rails_api_authentication_warden/)\n","funding_links":[],"categories":["Hanami Project List"],"sub_categories":["Play/Pet projects"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickgnd%2Fhanami-jwt-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickgnd%2Fhanami-jwt-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickgnd%2Fhanami-jwt-example/lists"}