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

无需登录的Rails API鉴权实现:公开数据访问权限管控

嘿,这个需求其实挺常见的——既要给API加上必要的访问限制防止滥用,又得保持物品列表对所有用户(包括未登录的)开放查看。下面给你几个实用的方案,你可以根据实际场景组合使用:

方案1:给公开接口加限流(防止恶意请求)

这是最基础也最有效的保护方式,能避免爬虫或者恶意脚本频繁刷你的API。推荐用rack-attack这个Rails生态里的成熟工具:

  • 先在Gemfile里添加依赖:

    gem 'rack-attack'
    

    运行bundle install安装。

  • 生成初始化配置文件:

    rails generate rack:attack
    
  • 在config/initializers/rack_attack.rb里配置限流规则,比如给匿名用户限制每分钟最多10次请求(数值可以根据你的业务调整):

    # 针对匿名用户的物品列表接口限流
    Rack::Attack.throttle('anon/items', limit: 10, period: 1.minute) do |req|
      if req.path == '/items' && req.get?
        # 用IP地址标识匿名用户
        req.ip
      end
    end
    
    # 如果有登录用户,可以给他们放宽限制
    Rack::Attack.throttle('auth/items', limit: 100, period: 1.minute) do |req|
      if req.path == '/items' && req.get? && req.session[:user_id].present?
        req.session[:user_id]
      end
    end
    

这样既拦住了恶意请求,完全不影响正常用户查看列表。

方案2:开启CSRF保护(同域前端场景)

既然你的前端和API是同域的(都是localhost:3000),可以开启Rails的CSRF保护,确保请求只能来自你的官方站点,防止跨站伪造请求:

  • 在app/controllers/application_controller.rb里确保CSRF保护生效:

    class ApplicationController < ActionController::API
      include ActionController::RequestForgeryProtection
    
      # 针对JSON请求也开启CSRF保护(需要前端配合传递token)
      protect_from_forgery with: :exception
    end
    
  • 前端这边要在axios请求里带上CSRF token:
    先在页面布局里添加meta标签:

    <meta name="csrf-token" content="<%= form_authenticity_token %>">
    

    然后在axios的全局配置里设置:

    import axios from 'axios';
    
    const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
    axios.defaults.headers.common['X-CSRF-Token'] = csrfToken;
    

这样只有来自你自己站点的请求才能成功调用API,避免其他网站伪造请求。

方案3:权限控制(区分不同动作的访问权限)

如果你的Items控制器还有创建、修改、删除这类敏感动作,可以用权限gem(比如Pundit)来做细粒度控制,只开放index动作给匿名用户:

  • 安装Pundit:

    gem 'pundit'
    

    运行bundle install后生成配置:

    rails generate pundit:install
    
  • 创建Item的权限策略:

    rails generate pundit:policy item
    
  • 在app/policies/item_policy.rb里配置权限:

    class ItemPolicy < ApplicationPolicy
      # 允许所有用户(包括匿名)查看列表
      def index?
        true
      end
    
      # 只有登录用户才能创建物品
      def create?
        user.present?
      end
    
      # 其他动作(比如update/destroy)可以按需配置权限
    end
    
  • 在Items控制器里应用权限控制:

    class ItemsController < ApplicationController
      # 除了index,其他动作都需要登录
      before_action :authenticate_user!, except: [:index]
      after_action :verify_authorized, except: [:index]
    
      def index
        @items = Item.all
        render json: @items
      end
    
      # 其他动作...
    end
    

这样既保护了修改类的敏感接口,又完全不影响匿名用户查看物品列表。

总结

你可以根据实际需求组合这些方案:

  • 如果主要担心API被滥用,优先用方案1的限流;
  • 同域场景下,加上方案2的CSRF保护会更安全;
  • 有敏感操作的话,用方案3的权限控制区分不同动作的访问权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:35:00