Skip to content

nickgnd/hanami-jwt-example

Repository files navigation

JSON API with Hanami 🌸

The goal of this project is to provide an example of a JSON API web application built with Hanami that exposes JWT-protected enpoints.

Main features:

Developed and tested with:

  • Ruby v2.3.1
  • Hanami v1.0

Try it yourself

git clone https://github.com/nickgnd/hanami-jwt-example
cd hanami-jwt-example
bundle install

then edit .env.* files to fit your environment and create the development and test databases

bundle exec hanami db create
bundle exec hanami db migrate
HANAMI_ENV=test bundle exec db create
HANAMI_ENV=test bundle exec hanami db migrate

finally, run tests to check if everything is ok

rake test

The web application exposes an API which allows authenticated users to retrieve a collection of items. The requests to this endpoint will be authenticated through a token based authentication strategy, passing a custom header Authorization containing the user's JWT.

Let's start.

bundle exec hanami server

By default it launches the development server at http://localhost:2300

  1. Before we need to register a new user

To do this, we have to make a POST request against /registration endpoint passing the required informations in the payload.

request:POST /registration

payload:

{ user: { email: "[email protected]", password: "cherryblossom", password_confirmation: "cherryblossom" } }

with curl:

curl -X POST -H "Accept: application/json" -H "Content-Type: application/json" -d '{ "user": { "email": "[email protected]", "password": "cherryblossom", "password_confirmation": "cherryblossom" } }' "http://localhost:2300/registration"
  1. Retrive user's jwt

For retrieving the JWT, we have to make a POST request to /sessions path passing user's email and password in the payload.

request: POST /sessions

payload:

{ user: { email: "[email protected]", password: "cherryblossom" } }

The response body will contain the JWT under the key auth_token, save it for the next step (retrieving item collections).

with curl:

curl -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{ "user": { "email": "[email protected]", "password": "cherryblossom" } }' "http://localhost:2300/sessions"

Response example:

{"auth_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxNCwiaXNzIjoiaHR0cDovL2ludmVudG9yeS5jb20iLCJleHAiOjE0ODkwNDUxNDB9.RI2F5-6rsIU02yXa158iocRP2qKQoR-mi8jbsRM0mDo"}
  1. Retrieving items

Finally, for retrieving the items we have to make a GET request against /items endpoint including the user's jwt in the headers.

request: GET /items

headers: "Authentication": "Bearer <YOUR_JWT>"

with curl:

curl -X GET -H "Content-Type: application/json" -H "Accept: application/json" -H "Authorization: Bearer <YOUR_JWT>" "http://localhost:2300/items"

The 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:

bundle exec hanami console
item = Item.new(code: 'alfa', available: true)
=> #<Item:0x007fa66b2da7d0 @attributes={:code=>"alfa", :available=>true}>

ItemRepository.new.create(item)
=> #<Item:0x007fa66e040e18 @attributes={:id=>1, :code=>"alfa", :available=>true, :created_at=>2017-03-08 23:00:11 UTC, :updated_at=>2017-03-08 23:00:11 UTC}>

Now the next request will return the item just created

[
  { "id":1,"code":"alfa","available":true,"created_at":"2017-03-08 23:00:11 UTC","updated_at":"2017-03-08 23:00:11 UTC" }
]

et voilà!

Contributing

Feel free to submit issues for questions, bugs and enhancements.

and as usual...

  1. Fork the repo
  2. Create your feature branch
  3. Commit changes to your own branch
  4. Push it
  5. Submit a Pull Request

Credits

This project is inspired by this tutorial Using rails-api to build an authenticated JSON API with warden