Rails 8 is here, bringing new features and changes to improve the security and ease of developing web applications. One key update focuses on authentication, which protects user accounts and data. With Rails 8, authentication is more secure and easier to implement, thanks to enhancements in the framework and improved integration options. In this guide, we’ll cover the updates Rails 8 brings to authentication, including code examples, so you can secure your app confidently and efficiently.
Why Authentication Matters in Rails Applications
Authentication is the process of verifying user identity in an app, ensuring only authorized users gain access to their accounts or sensitive features. Poor authentication leads to security issues, including data breaches and account compromises. Rails 8 has made authentication easier to integrate while introducing stronger encryption and improved integration with external services.
Key Authentication Changes in Rails 8
Stronger Default Encryption
Rails 8 now defaults to stronger encryption algorithms for password storage. This change minimizes the risk of password breaches and helps your app comply with modern security standards.
Code Example for Encryption:
# In User model
has_secure_password
Rails 8 uses bcrypt by default for encrypting passwords, ensuring strong security without additional setup.
Improved Devise Integration
Devise, the popular authentication gem for Rails, now fully supports Rails 8, taking advantage of framework improvements. New configurations allow seamless multi-factor authentication and social login options.
Code Example with Devise:
# Gemfile
gem 'devise'
# Terminal command to install Devise
rails generate devise:install
# Create a User model with Devise
rails generate devise User
After setting up Devise, Rails 8 enables smooth integration with popular social login providers and multi-factor options.
Turbo-Stream Support for Authentication Forms
Rails 8’s Turbo framework simplifies AJAX-like behavior, helping you create fast-loading, interactive authentication forms. Turbo Streams let you update only specific parts of a page when users log in or sign up, creating a smooth experience without full-page reloads.
Turbo Stream Example:
# app/views/sessions/new.html.erb
<%= form_with url: login_path, method: :post, data: { turbo_stream: true } do |f| %>
<%= f.label :email %>
<%= f.email_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Login" %>
<% end %>
# app/views/sessions/create.turbo_stream.erb
<%= turbo_stream.replace "login_form" do %>
<p>Login successful!</p>
<% end %>
With Turbo, users get instant feedback when logging in, enhancing the overall app experience.
Enhanced JWT (JSON Web Token) Support in Rails 8
For APIs, Rails 8 now includes built-in support for JWT, streamlining token-based authentication. This approach is ideal for single-page applications (SPAs) or mobile apps that require session persistence across devices.
JWT Authentication Example:
# app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def create
user = User.find_by(email: params[:email])
if user&.authenticate(params[:password])
token = encode_token({ user_id: user.id })
render json: { token: token }, status: :created
else
render json: { error: 'Invalid credentials' }, status: :unauthorized
end
end
private
def encode_token(payload)
JWT.encode(payload, Rails.application.secrets.secret_key_base)
end
end
This setup provides a secure way to handle API authentication, issuing tokens that your app can verify for authorized requests.
Session-Based Authentication and CSRF Protection in Rails 8
Rails 8 retains session-based authentication, adding further improvements to CSRF (Cross-Site Request Forgery) protection, which prevents malicious requests from compromising user sessions. By default, CSRF tokens are automatically included in Rails 8 forms, preventing malicious users from submitting forged requests on behalf of authenticated users.
If you’re handling sensitive operations (e.g., changing user email or deleting records), Rails automatically protects these routes from CSRF attacks.
Code Example for CSRF:
# ApplicationController
protect_from_forgery with: :exception
Enabling CSRF protection is simple in Rails 8 and ensures that form submissions originate from authorized users only.
Setting Up Authentication in a Rails 8 App: Step-by-Step Guide
Step 1: Create a New Rails 8 Project
To get started, create a new Rails 8 app:
rails new myapp --database=postgresql
Step 2: Add the Devise Gem
Devise simplifies user authentication, making it easy to handle user sessions and password encryption.
# Gemfile
gem 'devise'
Then, run:
bundle install
rails generate devise:install
Step 3: Generate the User Model with Devise
Use Devise to create a User model, adding default fields for email and password.
rails generate devise User
rails db:migrate
This will add routes, controllers, and views needed for user authentication.
Step 4: Implement Social Login with OmniAuth
Adding social login improves user experience by enabling login with Google, GitHub, or other providers. With Devise, Rails simplifies the process using OmniAuth.
OmniAuth Example:
# Gemfile
gem 'omniauth-google-oauth2'
# Configuring Devise for OmniAuth in config/initializers/devise.rb
config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']
# In User model (user.rb)
devise :omniauthable, omniauth_providers: [:google_oauth2]
This setup lets users log in with their Google accounts, reducing sign-up friction.
Step 5: Secure Your App with Multi-Factor Authentication
Multi-factor authentication (MFA) requires a user to verify their identity with an additional code (often sent to their phone) after entering a password. Use a library like authy
or google-authenticator
for Rails apps.
Code Example for MFA:
# Using a simple approach with Devise’s two-factor authentication
gem 'devise-two-factor'
# Add two-factor authentication to the User model
devise :two_factor_authenticatable, :otp_secret_encryption_key => ENV['OTP_SECRET_KEY']
This setup provides an additional layer of security, protecting user accounts even if passwords are compromised.
Creating a Secure API with Rails 8
APIs require token-based authentication, typically using JWT. Rails 8 streamlines this process with built-in support for handling JWTs.
Step 1: Set Up JWT Authentication
Use the jwt
gem for encoding and decoding tokens.
# Gemfile
gem 'jwt'
Code Example:
# app/controllers/api/v1/sessions_controller.rb
def create
user = User.find_by(email: params[:email])
if user&.authenticate(params[:password])
token = encode_token({ user_id: user.id })
render json: { token: token }, status: :created
else
render json: { error: 'Invalid email or password' }, status: :unauthorized
end
end
private
def encode_token(payload)
JWT.encode(payload, Rails.application.secrets.secret_key_base)
end
Step 2: Decode Tokens in Secure Endpoints
Decode tokens to verify user access in protected API routes.
# app/controllers/application_controller.rb
def decoded_token
token = request.headers['Authorization']
JWT.decode(token, Rails.application.secrets.secret_key_base, true, algorithm: 'HS256')
end
Password Recovery Enhancements in Rails 8
Simplified Password Recovery Flow
Rails 8 makes it easier to implement password recovery by offering a few helper methods to send password reset emails. Here’s a basic example of how to set up password recovery:
# app/controllers/passwords_controller.rb
class PasswordsController < ApplicationController
def new
@user = User.new
end
def create
@user = User.find_by(email: params[:email])
if @user
@user.send_password_reset
flash[:notice] = "Password reset instructions sent to your email"
redirect_to login_path
else
flash[:alert] = "Email address not found"
render :new
end
end
end
Sending Password Reset Instructions
In the User
model, you can add a method to send the reset instructions:
class User < ApplicationRecord
has_secure_password
def send_password_reset
token = SecureRandom.urlsafe_base64
update!(reset_token: token, reset_sent_at: Time.now)
UserMailer.password_reset(self).deliver_now
end
end
This flow allows users to reset their password securely through an emailed link.
WebAuthn Support for Biometric and Hardware Authentication in Rails 8
WebAuthn allows users to authenticate using biometrics (like a fingerprint or face ID) or hardware devices. Rails 8 supports WebAuthn natively, bringing high-level security to applications that require it.
Benefits of WebAuthn in Rails 8
- Improved User Experience: Biometric logins are faster and more secure.
- Reduced Risk of Credential Theft: Users don’t need passwords, so there’s nothing to steal.
- Compliance with Security Standards: WebAuthn meets the latest security regulations, useful for applications needing compliance.
WebAuthn is perfect for banking or government applications, where security is paramount.
Rails 8 Authentication: Key Takeaways
Rails 8 Authentication offers:
- Modern Protocol Support (OAuth 2.0, OpenID Connect)
- Enhanced Token and Session Management
- Passwordless Options for a frictionless user experience
- MFA and WebAuthn for high-security needs
It simplifies and strengthens authentication, allowing you to build secure apps faster. With its modern protocols, passwordless logins, and advanced token management, Rails 8 is set to support secure and scalable applications for years to come.
Final Thoughts on Rails 8 Authentication
Rails 8 has brought essential improvements in security and ease of use for authentication. By following these updates, you can build apps with stronger security measures and smoother login processes. Whether you’re creating a user-friendly web app with Devise or a secure API with JWT, Rails 8’s enhancements make it easier than ever to implement modern, reliable authentication.
Remember, security is a moving target, so it’s crucial to stay updated with Rails releases and integrate best practices into your app as new features and vulnerabilities emerge. Rails 8 empowers you to create secure, user-friendly apps while keeping authentication simple and manageable.