尝试访问由 Devise JWT 保护的 API 时出现“没有可用的验证密钥”

问题描述 投票:0回答:5

我安装了 gem

devise-jwt
。我可以执行登录请求,并收到授权令牌作为回报,但是当我尝试访问安全端点时,我收到消息:
No verification key available.

blaine@devbox:~/langsite/backend [master] $ curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIwZWNjMmIzNi04ZmZiLTQ2Y2QtYTZkNi1iZGRjZmU4YTQxNmMiLCJzdWIiOiIxIiwic2NwIjoidXNlciIsImF1ZCI6bnVsbCwiaWF0IjoxNjA1ODQ2NjczLCJleHAiOjE2MDU4NzU0NzN9.ZyqvylXeLZbrRM2V2s5qsyHxiGgElng58HwQ8qjOHCU" http://localhost:3001/quiz_sentences.json
{"error":"No verification key available"}

这就是我的

config/initializers/devise.rb
文件中的内容:

config.jwt do |jwt|
    jwt.secret = Rails.application.credentials.secret_key_jwt
    jwt.dispatch_requests = [
        ['POST', %r{^/users/sign_in$}],
        ['GET', %r{^/$}]
    ]
    jwt.request_formats = { user: [:json] }
    jwt.expiration_time = 8.hours.to_i
end

我可以正常登录并接收授权令牌:

blaine@devbox:~/langsite/backend [master] $ curl -D - -X POST -d "user[email][email protected]&user[password]=blaine" http://localhost:3001/users/sign_in.json
HTTP/1.1 201 Created
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: strict-origin-when-cross-origin
Location: /
Content-Type: application/json; charset=utf-8
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIwZWNjMmIzNi04ZmZiLTQ2Y2QtYTZkNi1iZGRjZmU4YTQxNmMiLCJzdWIiOiIxIiwic2NwIjoidXNlciIsImF1ZCI6bnVsbCwiaWF0IjoxNjA1ODQ4MDQ2LCJleHAiOjE2MDU4NzY4NDZ9.66Hg_NG3E79-ybC4rJK_XkkSxpLcWHWTlOiw96hyvjg
ETag: W/"cfe36cdecee4080492f63e8c8f0c091b"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: c961fc61-a1b4-49f0-bc16-63f19a0abd22
X-Runtime: 0.279213
Vary: Origin
Transfer-Encoding: chunked

看来我也暴露了授权标头:

Rails.application.config.middleware.insert_before 0, Rack::Cors do
    allow do
        origins '*'
        resource('*',
            headers: :any,
            expose: ["Authorization"],
            methods: :any
        )
    end
end

我的用户模型:

class User < ApplicationRecord
    include Devise::JWT::RevocationStrategies::JTIMatcher
    # Include default devise modules. Others available are:
    # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
    devise :database_authenticatable, :registerable, :recoverable,
    :rememberable, :validatable, :jwt_authenticatable, jwt_revocation_strategy: self
end

我很困惑,非常感谢任何帮助。谢谢。

ruby-on-rails devise devise-jwt
5个回答
18
投票

TLDR;确认

jwt.secret
确实已设置

我也遇到了同样的问题,就我而言,这是因为通过

jwt.secret
启动 Puma 时未正确读取
systemd
造成的。

config.jwt do |jwt|
 jwt.secret = ENV['JWT_SECRET_KEY'] # was blank, only if starting via systemd or other daemon
 jwt.dispatch_requests = [
   ['POST', %r{^/login$}]
 ]
 jwt.revocation_requests = [
   ['DELETE', %r{^/logout$}]
 ]
 jwt.expiration_time = 2.weeks.to_i
end

由于某种原因,在远程服务器上,当通过

systemd
服务启动时,
env['JWT_SECRET_KEY']
为空。但是,手动启动 Puma 时,效果很好。

我通过硬编码一个字符串作为秘密发现了这一点。突然就成功了。

config.jwt do |jwt|
 jwt.secret = "012345678901234567890123456789" # Suddenly worked
 jwt.dispatch_requests = [
   ['POST', %r{^/login$}]
 ]
 jwt.revocation_requests = [
   ['DELETE', %r{^/logout$}]
 ]
 jwt.expiration_time = 2.weeks.to_i
end 

如果

jwt.secret
为空,无论出于何种原因它仍然会生成
auth token
。就像你一样,这让我很失望,因为它让我认为我的设置是正确的。


要测试您是否遇到类似问题,请暂时将乱码硬编码为秘密。如果有效,那么您就走在正确的道路上

显然,您不应该对字符串进行硬编码,而应该检查并确认您的秘密是否已正确输入到上述配置中。

对我来说,这意味着在

EnvironmentFile
服务配置中指定
systemd
,其中包含
key=value
对(很像
dotenv
文件)。


1
投票

这个问题与我的问题相符,但让我对这个问题有了不同的答案:ruby on Rails:heroku:“生产”环境缺少“secret_key_base”

对于遇到此问题的其他人 - 检查您是否使用 Rails.application.secret_key_base (而不是 Rails.application.secrets.secret_key_base)


0
投票

我通过使用warden-jwt_auth 得到了这个错误。 0.7.0 崩溃了,但降级到 0.6.0 可以。如果有人遇到这个:)可能会有所帮助


0
投票

此外,如果您正在使用容器,请在

docker-compose
中或在构建容器时传递环境变量。如果你只是将其写入
.env
文件中,程序不会读取它


0
投票

我的测试失败了(但仅在生产中),所以我为我的 user_spec 创建了一个假 hmac_secret:

let(:hmac_secret) { 'MyNameIs-RamA-LolI-LoVE-CATSorDooI42' }

before do
  allow(user).to receive(:hmac_secret).and_return(hmac_secret)
end
© www.soinside.com 2019 - 2024. All rights reserved.