When we create an API in Ruby on Rails, it is important to control who has access to resources. Here are the main approaches to authentication:
Basic Authentication
The simplest, but least secure method. In Basic Authentication, the Authorization header transmits username and password encoded in Base64.
Header format:
Authorization: Basic <base64_string>
<base64_string> = Base64-encoded string username:password
For example, if you have:
- username = apiuser
- password = secret123
First, we form the string:
apiuser:secret123
Next, we encode it in Base64:
require 'base64'
credentials = "apiuser:secret123"
encoded = Base64.strict_encode64(credentials)
puts encoded
# => YXBpdXNlcjpzZWNyZXQxMjM=
So, the header will look like this:
Authorization: Basic YXBpdXNlcjpzZWNyZXQxMjM=
When Rails sees Authorization: Basic ..., the method authenticate_or_request_with_http_basic decodes Base64, splits username:password, and checks them on the server.
Token Authentication
The user receives a
unique token that is added to each request.
A more secure option for mobile or frontend applications.
class Api::V1::BaseController < ApplicationController
before_action :authenticate_user!
private
def authenticate_user!
token = request.headers['Authorization']&.split(' ')&.last
@current_user = User.find_by(api_token: token)
render json: { error: 'Unauthorized' }, status: :unauthorized unless @current_user
end
end
Request header:
Authorization: Token abc123
JWT (JSON Web Token)
A popular method for stateless API. The server does not store sessions, and the client sends a signed token.
Example with the jwt gem:
# Creating a token
payload = { user_id: user.id, exp: 24.hours.from_now.to_i }
token = JWT.encode(payload, Rails.application.secret_key_base)
# Verifying the token
decoded = JWT.decode(token, Rails.application.secret_key_base).first
user_id = decoded["user_id"]
Header:
Authorization: Bearer <jwt_token>
OAuth 2.0
A standard for authorization and access to resources through third-party services or APIs.
To create your own OAuth 2 server in Rails, use
Doorkeeper:
# Gemfile
gem 'doorkeeper'
After configuration, you can issue access tokens to external clients:
Authorization: Bearer <access_token>
If you need to allow users to log in through third-party services (Google, Facebook, GitHub), use OmniAuth in conjunction with Devise for authentication.
In simple terms: Doorkeeper — for API access, OmniAuth — for user login through other services.