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
Authorizationheader 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
jwtgem 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.