[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 It will create a ruby file, app/controllers/v1/users_controller.rb module V1 class UsersController

Jan 18, 2025 - 16:39
[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

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

Update the Routes Config

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

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\"}

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

{"token":""}

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 "

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"
  }
}

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.