0
0
RailsHow-ToBeginner · 4 min read

How to Implement JWT Authentication in Rails Easily

To implement JWT authentication in Rails, use the jwt gem to encode and decode tokens. Create a controller to handle user login that returns a token, and use a before_action to verify the token on protected routes.
📐

Syntax

The main parts of JWT auth in Rails include:

  • Encoding a token: Use JWT.encode(payload, secret_key) to create a token with user data.
  • Decoding a token: Use JWT.decode(token, secret_key) to verify and extract data.
  • Authentication controller: Handles login and returns the token.
  • Authorization filter: Checks token validity before protected actions.
ruby
payload = { user_id: user.id, exp: 24.hours.from_now.to_i }
secret_key = Rails.application.secrets.secret_key_base

# Encoding
token = JWT.encode(payload, secret_key)

# Decoding
decoded_token = JWT.decode(token, secret_key)[0]
user_id = decoded_token['user_id']
💻

Example

This example shows a simple Rails controller for login that returns a JWT token and a method to authenticate requests using the token.

ruby
class AuthenticationController < ApplicationController
  SECRET_KEY = Rails.application.secrets.secret_key_base.to_s

  def login
    user = User.find_by(email: params[:email])
    if user&.authenticate(params[:password])
      token = encode_token(user_id: user.id)
      render json: { token: token }, status: :ok
    else
      render json: { error: 'Invalid email or password' }, status: :unauthorized
    end
  end

  private

  def encode_token(payload)
    payload[:exp] = 24.hours.from_now.to_i
    JWT.encode(payload, SECRET_KEY)
  end

  def authenticate_request
    header = request.headers['Authorization']
    token = header.split(' ').last if header
    begin
      decoded = JWT.decode(token, SECRET_KEY)[0]
      @current_user = User.find(decoded['user_id'])
    rescue JWT::DecodeError, ActiveRecord::RecordNotFound
      render json: { error: 'Unauthorized' }, status: :unauthorized
    end
  end
end
Output
{"token":"eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE2NzM2NzQ0MDB9.abc123xyz"}
⚠️

Common Pitfalls

Common mistakes when implementing JWT auth in Rails include:

  • Not setting an expiration time on tokens, which can cause security risks.
  • Using a weak or hardcoded secret key instead of Rails secrets.
  • Failing to handle token decoding errors, leading to crashes.
  • Not sending the token in the Authorization header properly.
ruby
def encode_token(payload)
  # Wrong: no expiration
  JWT.encode(payload, 'hardcoded_secret')
end

# Correct way
SECRET_KEY = Rails.application.secrets.secret_key_base.to_s

def encode_token(payload)
  payload[:exp] = 24.hours.from_now.to_i
  JWT.encode(payload, SECRET_KEY)
end
📊

Quick Reference

Remember these key points for JWT auth in Rails:

  • Use jwt gem for encoding/decoding tokens.
  • Store your secret key securely in Rails secrets.
  • Always set token expiration.
  • Send tokens in Authorization: Bearer <token> header.
  • Handle errors gracefully to avoid crashes.

Key Takeaways

Use the jwt gem to encode and decode tokens securely in Rails.
Always set an expiration time on JWT tokens to improve security.
Store your secret key safely using Rails secrets or credentials.
Send JWT tokens in the Authorization header as Bearer tokens.
Handle token decoding errors to prevent unauthorized access and crashes.