Table of contentsClick link to navigate to the desired location
This content has been automatically translated from Ukrainian.
When we build an API in Ruby on Rails, it's important to control, who has access to resources. Here are the main approaches to authentication:
Basic Authentication
The simplest, but unsafe 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, form a line:
apiuser: secret123
Next, we encode it in Base64:
demand 'base64' credentials = "apiuser:secret123" encoded = Base64.strict_encode64(credentials) puts encoded # => YXBpdXNlcjpzZWNyZXQxMjM=
So the title is going to look like this:
Authorization: Basic YXBpdXNlcjpzZWNyZXQxMjM=
When Rails sees Authorization: Basic ..., method authenticate_or_request_with_http_basic decodes Base64, separates username:password and checks them on the server.
Token Authentication
The user receives unique token, which adds to each request. A more secure option for mobile or front-end applications.
class Api::V1::BaseController < ApplicationController
before_action:authenticate_user!
private
def authenticate_user!
token = request.heads['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 way for stateless API. The server does not save the session, and the client sends a signed token.
Example with jwt heme:
# Create token
payload = { user_id: user.id, exp: 24.hours.from_now.to_i }
token = JWT.encode(payload, Rails.application.secret_key_base)
# Token check
decoded = JWT.decode(token, Rails.application.secret_key_base).first
user_id = decoded["user_id"]
Heading:
Authorization: Bearer <jwt_token>
OAuth 2.0
Standard for authorization and access to resources through third-party services or APIs.
Rails uses servers to create its own OAuth 2 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 connection with Devise for authentication.
In simple words: Doorkeeper — for API access, OmniAuth — for user login through other services.
This post doesn't have any additions from the author yet.