You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 7仅API应用配置Devise-JWT遇Session禁用错误求助

解决Rails 7 API应用中Devise-JWT认证触发DisabledSessionError的问题

问题根源

仅API模式的Rails应用默认禁用会话存储,但Devise的authenticate_user!方法在认证失败时,会尝试写入flash消息并重定向到登录页,这个操作依赖会话支持,因此触发DisabledSessionError。另外,API应用的标准响应应为JSON格式,而非HTML重定向。

具体配置步骤

1. 调整Devise全局配置

编辑config/initializers/devise.rb,添加适配API场景的配置:

Devise.setup do |config|
  # 保留原有配置,新增以下内容
  # 针对token认证场景跳过会话存储
  config.skip_session_storage = [:http_auth, :token_auth]
  # 设置导航格式为JSON,避免默认的HTML重定向逻辑
  config.navigational_formats = [:json]
end

2. 自定义API控制器的认证失败响应

创建API专属父控制器app/controllers/api/v1/application_controller.rb,捕获会话错误并返回标准API响应:

class Api::V1::ApplicationController < ActionController::API
  rescue_from ActionDispatch::Request::Session::DisabledSessionError, with: :return_unauthorized

  private

  def return_unauthorized
    render json: { error: "未授权,请先登录" }, status: :unauthorized
  end
end

修改ClientsController继承该父控制器:

class Api::V1::ClientsController < Api::V1::ApplicationController
  before_action :authenticate_api_v1_user!

  def show
    render json: { message: "已认证,可访问资源" }
  end
end

3. 匹配Devise路由与认证helper

你的路由中devise_for :users位于api/v1命名空间下,对应的认证helper是authenticate_api_v1_user!,需确保控制器中使用该helper(如上代码所示),而非全局的authenticate_user!。

4. 确认Rails API模式的会话配置

在config/application.rb中确认已开启API模式并禁用会话:

module YourAppName
  class Application < Rails::Application
    config.api_only = true
    config.session_store :disabled
  end
end

注意事项

API应用的设计标准是返回JSON格式响应,你之前期望的HTML重定向属于传统Web应用行为,在API场景下应返回401 Unauthorized状态码及对应JSON错误信息。

内容的提问来源于stack exchange,提问作者Jeremy Thomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 00:06:25