Rails API-only应用Devise JWT认证失效问题排查
问题分析与解决方案
你的核心问题是authenticate_user!钩子未生效,导致受保护路由无需token即可访问,以下是关键排查点和修复方案:
1. 补全Devise JWT初始化配置
在config/initializers/devise.rb中必须添加JWT核心配置,否则Devise不会启用JWT认证策略:
Devise.setup do |config| # 保留原有Devise配置,新增JWT相关设置 config.jwt do |jwt| # 从credentials获取密钥(推荐),也可直接设置(不硬编码) jwt.secret = Rails.application.credentials.devise_jwt_secret_key! # 设置token过期时间 jwt.expiration_time = 1.day.to_i # 指定返回JWT的请求(比如登录接口) jwt.dispatch_requests = [['POST', %r{^/users/sign_in$}]] # 指定撤销JWT的请求(比如登出接口) jwt.revocation_requests = [['DELETE', %r{^/users/sign_out$}]] end end
可通过rails credentials:edit添加devise_jwt_secret_key密钥值。
2. 确保ApplicationController继承正确基类
API-only应用的控制器基类必须是ActionController::API,而非默认的ActionController::Base,否则Devise的API认证逻辑无法正常工作:
class ApplicationController < ActionController::API # 全局配置... end
3. 移除UsersController中重复的注册逻辑
你已自定义Users::RegistrationsController处理注册,但又在UsersController中写了create方法,这会导致路由冲突,且自定义的create不会触发Devise的JWT生成逻辑。直接删除UsersController中的create方法,让注册请求走Devise的注册控制器。
4. 验证路由配置正确性
确保config/routes.rb中正确映射Devise控制器和受保护路由:
Rails.application.routes.draw do # 自定义Devise控制器路由 devise_for :users, controllers: { registrations: 'users/registrations', sessions: 'users/sessions' # 若自定义会话控制器需添加 } # 受保护的用户路由,需通过authenticate_user!校验 resources :users, only: [:show] end
5. 确认token传递格式
访问受保护路由时,必须在请求头中按以下格式携带JWT token:
Authorization: Bearer <你的JWT令牌>
未按此格式传递会导致Devise无法识别token,认证校验失效。
额外检查
- 确认
User模型中jwt_revocation_strategy: self配置正确(已包含Devise::JWT::RevocationStrategies::JTIMatcher模块) - 重启Rails服务器,确保所有配置变更生效
内容的提问来源于stack exchange,提问作者MOin
相关产品推荐
相关产品推荐

