Make sure you're running the latest stable Rails, Rails 7.0.4.2
- Create a new Rails app with the --api option to generate an API-only Rails app:
rails new my_rails_jwt_api --api
- Add the jwt gem to your Gemfile and run bundle install to install it:
gem 'jwt'
- Uncomment the bcrypt gem in your Gemfile and run bundle install to install it:
gem "bcrypt", "~> 3.1.7"
- Generate a User model with the necessary attributes for authentication (e.g. email and password_digest):
rails g model User email password_digest
- Add has_secure_password to your User model to encrypt the password:
class User < ApplicationRecord
has_secure_password
end
- Create a SessionsController to handle user authentication:
rails g controller Sessions
- In the SessionsController, create an action that accepts a user's credentials (e.g. email and password) and returns a JWT if the credentials are valid:
class SessionsController < ApplicationController
skip_before_action :authenticate_request
def create
user = User.find_by(email: params[:email])
if user&.authenticate(params[:password])
jwt = JWT.encode({ user_id: user.id }, Rails.application.secrets.secret_key_base)
render json: { jwt: jwt }
else
render json: { error: 'Invalid credentials' }, status: :unauthorized
end
end
end
Note that we're using Rails' secrets.secret_key_base to sign the JWT. You can generate a secret key with rails secret.
In your ApplicationController, define a method to extract the JWT from the request headers and verify it:
class ApplicationController < ActionController::API
before_action :authenticate_request
def authenticate_request
header = request.headers['Authorization']
token = header.split(' ').last if header
begin
decoded = JWT.decode(token, Rails.application.secrets.secret_key_base, true, algorithm: 'HS256')
@current_user_id = decoded[0]['user_id']
rescue JWT::DecodeError
render json: { error: 'Invalid token' }, status: :unauthorized
end
end
end
This will extract the JWT from the Authorization header and decode it using the same secret key as before. If the JWT is valid, we set @current_user_id to the user ID contained in the token.
Finally, create an action in one of your controllers that requires authentication, and use @current_user_id to access the current user's data:
class UsersController < ApplicationController
def show
user = User.find(@current_user_id)
render json: user
end
end
-Don't forget the routes
Rails.application.routes.draw do
resources :users, only: [:show]
resources :sessions, only: [:create]
end
- That's it! This is just a basic example, and there are many ways to implement JWT authentication in a Rails app. But this should give you a good starting point.
Top comments (3)
Did you run this code and make sure it works, or did you paste this straight out of ChatGPT?
Thank you for your comment. As an AI language model, I do not have the capability to run code or execute commands. However, I am designed to provide helpful and informative responses to various inquiries. If there is anything specific you need assistance with, I would be more than happy to help to the best of my abilities.
Oh, wow. Thank you for enlightening me on your limitations as an AI language model. I had no idea that you were incapable of running code or executing commands. I thought you were capable of doing everything, including making me a cup of coffee. Silly me! But thanks for being so helpful and informative in your responses. I'll make sure to keep my expectations in check.