Rails 7:使用Devise和JWT进行身份验证的API-only应用程序
文章目录
使用 Devise 和 JWT 构建 Rails 7 API-only 应用程序
在本文中,我们将介绍如何在 Rails 7 中使用 Devise 和 JWT 实现用户身份验证,并结合 JSON:API 序列化器来处理数据格式化。以下内容将详细讲解从安装到配置的完整流程,帮助你快速上手。
配置 Devise、JWT 和 JSON:API 序列化器
在开始之前,我们需要安装以下 gem:
- Devise:处理用户身份验证的核心 gem,提供用户创建和会话管理功能。
- Devise-JWT:Devise 的扩展,用于生成和验证 JWT(JSON Web Token)。
- JSON:API Serializer:用于将 Ruby 对象序列化为符合 JSON:API 规范的格式。
在 Gemfile 中添加以下依赖:
gem 'devise'
gem 'devise-jwt'
gem 'jsonapi-serializer'
然后运行以下命令安装这些 gem:
bundle install
配置 Devise
安装 Devise
运行以下命令生成 Devise 的初始化文件:
rails g devise:install
编辑生成的 config/initializers/devise.rb 文件,确保以下配置:
config.navigational_formats = []
这将禁用默认的 Flash 消息功能,因为在 API-only 模式下 Flash 消息是无效的。
配置开发环境
在 config/environments/development.rb 文件末尾添加以下行:
config.action_mailer.default_url_options = { host: 'localhost', port: 3001 }
我们将 Rails API 服务运行在端口 3001,而前端(如 React 应用)运行在默认的 3000 端口。为此,还需要更新 config/puma.rb 文件中的端口配置:
port ENV.fetch('PORT') { 3001 }
创建用户模型
运行以下命令生成用户模型:
rails g devise User
然后执行数据库迁移:
rails db:create db:migrate
生成 Devise 控制器
为了自定义用户登录和注册逻辑,我们需要生成 Devise 的控制器:
rails g devise:controllers users -c sessions registrations
在生成的控制器中,确保它们可以响应 JSON 格式:
class Users::SessionsController < Devise::SessionsController
respond_to :json
end
class Users::RegistrationsController < Devise::RegistrationsController
respond_to :json
end
自定义路由
在 config/routes.rb 中覆盖默认路由,并添加自定义路径别名:
Rails.application.routes.draw do
devise_for :users, path: '', path_names: {
sign_in: 'login',
sign_out: 'logout',
registration: 'signup'
},
controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations'
}
end
添加额外的用户字段
如果需要在用户注册时添加额外字段(如姓名和头像),可以在 ApplicationController 中配置允许的参数:
class ApplicationController < ActionController::API
before_action :configure_permitted_parameters, if: :devise_controller?
protected def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: %i[name avatar])
devise_parameter_sanitizer.permit(:account_update, keys: %i[name avatar])
end
end
接着创建迁移文件,为用户表添加 name 字段:
rails g migration AddNameToUsers name:string
rails db:migrate
配置 Devise-JWT
生成 JWT 密钥
JWT 需要使用私钥进行签名。运行以下命令生成密钥:
bundle exec rails secret
将生成的密钥添加到加密的凭据文件中:
EDITOR='code --wait' rails credentials:edit
在打开的文件中添加以下内容:
devise_jwt_secret_key:
配置 JWT
编辑 config/initializers/devise.rb 文件,添加以下配置:
config.jwt do |jwt| jwt.secret = Rails.application.credentials.devise_jwt_secret_key!
jwt.dispatch_requests = [
['POST', %r{^/login$}]
]
jwt.revocation_requests = [
['DELETE', %r{^/logout$}]
]
jwt.expiration_time = 30.minutes.to_i
end
这段代码指定了 JWT 的分发和撤销规则,并将令牌的有效期设置为 30 分钟。
配置撤销策略
为了安全性,我们需要在用户模型中添加 JTI(JWT ID)字段,并使用 JTIMatcher 策略管理令牌撤销。首先,创建迁移文件:
rails g migration AddJtiToUsers jti:string:index:unique
编辑生成的迁移文件,确保字段不可为空且唯一:
class AddJtiToUsers < ActiveRecord::Migration[7.0]
def change
add_column :users, :jti, :string, null: false
add_index :users, :jti, unique: true
end
end
运行迁移:
rails db:migrate
然后在用户模型中配置 JWT 策略:
class User < ApplicationRecord
include Devise::JWT::RevocationStrategies::JTIMatcher
devise :database_authenticatable, :registerable,
:recoverable, :validatable,
:jwt_authenticatable, jwt_revocation_strategy: self
end
使用 JSON:API Serializer
JSON:API Serializer 可以帮助我们按照 JSON:API 规范生成响应。安装 gem 后,为用户模型生成序列化器:
rails g serializer user id email name
生成的序列化器会包含指定的属性,可以通过以下方式调用:
UserSerializer.new(user).serializable_hash[:data][:attributes]
将 user 替换为实际的用户对象。
总结
通过本文的步骤,你已经成功配置了一个基于 Rails 7 的 API-only 应用程序,支持使用 Devise 和 JWT 进行身份验证,并使用 JSON:API Serializer 格式化数据。这种架构非常适合现代前后端分离的应用场景,能够提供高效、安全的用户认证服务。
原文链接: https://sdrmike.medium.com/rails-7-api-only-app-with-devise-and-jwt-for-authentication-1397211fb97c
最新文章
- 用 Poe-API-wrapper 连接 DALLE、ChatGPT,批量完成AI绘图或文字创作
- RESTful Web API 设计中要避免的 6 个常见错误
- LangGraph 工具详解:构建 AI 多步骤流程的关键利器
- GitHubAPI调用频率限制的增加方法
- 如何使用Route Optimization API优化配送路线
- 什么是聚类分析?
- 安全好用的OpenApi
- 医疗数据管理与fhir api的未来发展趋势
- 为什么要使用Google My Business Reviews API
- 2025年7月第2周GitHub热门API推荐:rustfs/rustfs、pocketbase/pocketbase、smallcloudai/refact
- API设计的首要原则
- 左手用R右手Python系列——百度地图API调用与地址解析/逆解析