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

如何在Rails中验证访问令牌?解决双重渲染与异常处理报错

解决Rails中的Double Render错误与用户认证问题

首先咱们来拆解你遇到的Double Render错误根源:在你原来的authenticate!方法里,当token无效时执行了render,但那个return只是退出了authenticate!方法本身,并没有终止整个请求的执行流程。之后get_user方法里的render json: {'hello' => 'hi'}还是会被执行,导致Rails检测到两次渲染操作,直接抛出错误。

下面给你两种可行的解决方案,按需选择:

方案一:直接修正认证方法的终止逻辑

在渲染错误信息后用and return来彻底终止请求流程,确保后续代码不会继续执行:

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  def authenticate!
    unless current_user
      render json: { 'error' => {'message' => 'Invalid access token', 'code' => 301 } } and return
    end
  end

  def current_user
    return @current_user if @current_user.present?
    user = User.find_by(access_token: params.delete(:token))
    @current_user = user if user.present?
    @current_user # 这里返回用户实例或nil,不要返回false,让判断逻辑更准确
  end
end

方案二:用异常处理实现(更符合Rails最佳实践)

你尝试的异常处理思路是对的,但存在两处小错误:

  1. 异常类名拼写错误:UnauthroizedAccess应该是UnauthorizedAccess
  2. rescue_from的第二个参数需要传方法符号(:render_invalid_access),不能直接调用方法

修正后的完整代码如下:

class ApplicationController < ActionController::Base
  # 定义自定义异常类
  class UnauthorizedAccess < StandardError; end

  protect_from_forgery with: :exception
  # 绑定异常与处理方法
  rescue_from UnauthorizedAccess, with: :render_invalid_access

  def authenticate!
    # 认证失败时抛出异常,中断请求流程
    raise UnauthorizedAccess, 'Invalid access token' unless current_user
  end

  def render_invalid_access
    render json: { 'error' => {'message' => 'Invalid access token', 'code' => 301 } }
  end

  def current_user
    return @current_user if @current_user.present?
    user = User.find_by(access_token: params.delete(:token))
    @current_user = user if user.present?
    @current_user
  end
end

这种方式的优势是把认证失败的逻辑和异常处理解耦,代码更清晰,还能在整个应用的控制器中统一处理未授权场景。

最后你的Api::V1::RegisterController不需要修改,保持原样即可,只要把返回内容改成用户信息就行:

class Api::V1::RegisterController < ApplicationController
  layout nil
  skip_before_action :verify_authenticity_token

  def get_user
    authenticate!
    # 认证通过时返回用户信息,替换成你需要的字段即可
    render json: current_user.as_json(only: [:id, :name, :email])
  end
end

这样修改后,token无效时会触发异常并返回错误提示;token有效时会正常返回用户信息,再也不会出现Double Render错误了。

内容的提问来源于stack exchange,提问作者Jasjeet Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:54:40