【问题标题】:RSPEC: How to test that a JSON Web Token is returned by controller actionRSPEC:如何测试控制器操作是否返回 JSON Web 令牌
【发布时间】:2023-04-09 16:13:02
【问题描述】:

我正在使用 Devise 和 JWT 对我正在编写的项目中的用户进行身份验证。我很难弄清楚如何编写一个有用的测试来期待 JWT response.body(因为每个都是加密的)。

我唯一能想到的就是测试它们的结构是否应该是 JWT(3 段,'.' 分隔字符串)。

有没有人遇到过测试随机/散列返回并提出更好的解决方案?

describe SessionTokensController, type: :controller do
  let(:current_user) { FactoryGirl.create(:user) }

  before(:each) do
    sign_in current_user
  end

  describe '#create' do
    it 'responds with a JWT' do
      post :create
      token = JSON.parse(response.body)['token']

      expect(token).to be_kind_of(String)
      segments = token.split('.')
      expect(segments.size).to eql(3)
    end
  end
end

【问题讨论】:

    标签: ruby-on-rails rspec jwt


    【解决方案1】:

    这真的取决于你到底想测试什么。

    如果您只是想测试返回的令牌是否存在且有效,您可以执行以下操作:

    it 'responds with a valid JWT' do
      post :create
      token = JSON.parse(response.body)['token']
    
      expect { JWT.decode(token, key) }.to_not raise_error(JWT::DecodeError)
    end
    

    虽然验证令牌包含的声明似乎更有用:

    let(:claims) { JWT.decode(JSON.parse(response.body)['token'], key) }
    
    it 'returns a JWT with valid claims' do
      post :create
      expect(claims['user_id']).to eq(123)
    end
    

    在后一个示例中,您可以验证 JWT 中包含的确切声明。

    【讨论】:

    • 需要调用JWT.decode token, nil, false否则调用会报错!
    • @wegginho 解码未签名的令牌并不是真正的练习,除非您使用未签名的令牌(您真的不应该这样做)......但你是对的,我错过了关键参数decode 方法调用。谢谢
    【解决方案2】:
        let(:user) { create(:user, password: "123456") }
    
          describe "POST authenticate_user" do
            context "with a valid password" do
              it "authenticates successfully" do
                post :authenticate_user, params:{email: user.email, password: "123456"}, format: :json
                parsed_body = JSON.parse(response.body)
                # binding.pry
                expect(parsed_body.keys).to match_array(["auth_token", "user"])
                expect(parsed_body['user']['email']).to eql("joe@gmail.com")
                expect(parsed_body['user']['id']).to eql(user.id)
              end
    
              it "authentication fails" do
                post :authenticate_user, params:{email: user.email, password: "123456789"}, format: :json
                parsed_body = JSON.parse(response.body)
                expect(parsed_body['errors'][0]).to eql("Invalid Username/Password")
              end
            end
          end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多