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

如何使用rswag测试带JWT认证与不带认证的API请求

如何使用rswag测试带JWT认证与不带认证的API请求

我太懂这种折腾的感觉了!之前用rswag测试API认证的时候,也卡在过“怎么同时测带token和不带token的场景”这个问题上,尤其是不带token的401情况,试了好几种方法都踩坑。别急,我来给你捋清楚怎么解决。

核心问题分析

你当前的全局Swagger配置里默认开启了security: [ { AuthToken: [] } ],这意味着所有请求都会默认要求带上JWT头。要测试不带token的场景,关键是在对应的response块里覆盖这个全局security设置,同时不要定义Authorization变量——这样rswag就不会自动添加这个请求头了。

具体解决方案

咱们直接修改你的测试代码,看关键改动:

首先,把请求块里的全局security配置去掉(因为每个response的认证需求不一样):

get 'retrieves a list of accessible unicorns' do
  tags 'unicorns'
  produces 'application/vnd.api+json'
  # 删掉原来的 security [ {AuthToken: [], NoAuth: []} ],改成在每个response里单独设置

然后针对每个response分别配置:

  1. 200 正常认证场景
    保持原来的逻辑,指定需要AuthToken,同时生成有效的JWT:
response '200', 'properly authenticated request' do
  security [ { AuthToken: [] } ] # 明确要求带认证头
  let(:Authorization) { JWT.encode({ auth: { user_id: user.pyx_user_id } }, nil, 'none') }
  run_test!
end
  1. 400 无效token场景
    同样需要带AuthToken,但传入错误的token值:
response '400', 'malformatted auth token' do
  security [ { AuthToken: [] } ]
  let(:Authorization) { 'AAABBBCCCDDDDEEE-invalid' }
  run_test!
end
  1. 401 无认证场景
    这里是关键:把security设为空数组,并且不定义Authorization变量,这样就不会发送认证头了:
response '401', 'no authentication' do
  security [] # 告诉rswag不需要任何认证头
  # 不要定义let(:Authorization),这样请求里就不会有这个头
  run_test!
end
  1. 401 有效但无权限场景
    如果还要测“有token但权限不够”的情况,同样指定AuthToken,生成一个合法但无权限的JWT即可:
response '401', 'valid but unauthorized' do
  security [ { AuthToken: [] } ]
  # 生成一个有权限问题的token,比如用无权限用户的id
  let(:unauthorized_user) { create(:user, account: account, role: :viewer) }
  let(:Authorization) { JWT.encode({ auth: { user_id: unauthorized_user.pyx_user_id } }, nil, 'none') }
  run_test!
end

为什么之前的方法不行?

  • 你尝试设置let(:Authorization) { nil }:这会发送一个Authorization: Bearer 的空值头,和“完全不发送头”是两种不同的请求,后端的认证逻辑可能会区别处理。
  • 你尝试在请求块里加多个securityScheme:rswag的请求块级security会应用到所有子response,没法单独控制,所以必须在每个response里单独配置security。

完整修改后的测试代码

RSpec.describe 'api/v1/unicorns', type: :request do
  path '/unicorns.json' do
    let(:user) { create(:perceptyx_owner) }
    let(:account) { create(:account, owners: [user]) }

    get 'retrieves a list of accessible unicorns' do
      tags 'unicorns'
      produces 'application/vnd.api+json'

      response '200', 'properly authenticated request' do
        security [ { AuthToken: [] } ]
        let(:Authorization) { JWT.encode({ auth: { user_id: user.pyx_user_id } }, nil, 'none') }
        run_test!
      end

      response '400', 'malformatted auth token' do
        security [ { AuthToken: [] } ]
        let(:Authorization) { 'AAABBBCCCDDDDEEE-invalid' }
        run_test!
      end

      response '401', 'no authentication' do
        security []
        run_test!
      end

      response '401', 'valid but unauthorized' do
        security [ { AuthToken: [] } ]
        let(:unauthorized_user) { create(:user, account: account, role: :viewer) }
        let(:Authorization) { JWT.encode({ auth: { user_id: unauthorized_user.pyx_user_id } }, nil, 'none') }
        run_test!
      end
    end
  end
end

这样修改后,每个场景都会按照预期发送对应的请求头,完美覆盖你需要的四种测试情况啦!

备注:内容来源于stack exchange,提问作者MustModify

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 08:53:15