DEV Community

ruwhan
ruwhan

Posted on

[Part 2] Rails 8 Authentication but with JWT

Overview

In the previous part, we've already covered how to setup, and encode our user object. There are still some parts missing, how do we decode and send the token, and how it will affect our API endpoints to be faster and more efficient.

The functions already there, in app/controllers/concern/Authentication.rb, we already have, decode, current_user, get_token, we gonna use them here.

Authenticating the Requests

We will need to create a new endpoint, for the first case, let's create a GET /users/me API endpoint.

rails g controller v1/UsersController
Enter fullscreen mode Exit fullscreen mode

It will create a ruby file, app/controllers/v1/users_controller.rb

module V1
  class UsersController < ApplicationController
    def me 
      if current_user
        render json: { user: current_user }, status: :ok
      else
        render json: { error: "Invalid token" }, status: :unauthorized
      end
    end
  end
end

Enter fullscreen mode Exit fullscreen mode

Update the Routes Config

  namespace :v1 do
    resources :auth, only: [:create]
    resources :users, only: [] do 
      collection do
        get :me
      end
    end
  end
Enter fullscreen mode Exit fullscreen mode

To recall, in the 1st part, we already create the current_user function in Authentication module, basically they just decode the token from the Authorization header, and will throw unauthenticated http error when token is not present or invalid.

Testing

Like we do in the first part of this article,

curl -X POST "http://localhost:5000/v1/auth" -H "Content-Type: application/json" -d "{\"email_address\": \"two@example.com\", \"password\": \"password\"}
Enter fullscreen mode Exit fullscreen mode

If everything going right, we should get the token in the response body:

{"token":"<AUTH_TOKEN>"}
Enter fullscreen mode Exit fullscreen mode

Get the current user object

Now, let's shoot the GET /users/me API endpoint, e.g, using curl:

curl "http://localhost:5000/v1/users/me" -H "Authorization: bearer <AUTH_TOKEN>"

Enter fullscreen mode Exit fullscreen mode

Since we are logged in using two@example.com user email address, we should expect that from the response body:

{
  "user": {
    "id": 298486374,
    "email_address": "two@example.com"
  }
}
Enter fullscreen mode Exit fullscreen mode

Of course, the user id can be different.

Source Code

The code available in the GitHub repository: https://github.com/ruwhan/rails_jwt, I also add a simple case how to use current authenticated user related with other models.

Conclusion

In this 2nd part of the article, we learn how JWT can eliminate database access to check authenticated user, while using some library that has token based authentication, we check database each time we want to get the current logged in user.

Top comments (0)