简体   繁体   English

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

[英]"No verification key available" when attempting to access API secured by Devise JWT

I have the gem devise-jwt installed.我安装了 gem devise-jwt I can perform a login request, and receive an Authorization token in return, but when I try to access a secured endpoint, I receive the message: No verification key available.我可以执行登录请求,并收到一个授权令牌作为回报,但是当我尝试访问安全端点时,我收到消息: 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"}

This is what I have in my config/initializers/devise.rb file:这是我在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

I can log in just fine and receive an Authorization token:我可以正常登录并收到授权令牌:

blaine@devbox:~/langsite/backend [master] $ curl -D - -X POST -d "user[email]=brlafreniere@gmail.com&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

It seems that I have the Authorization header exposed as well:似乎我也公开了 Authorization 标头:

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

My user model:我的用户模型:

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

I'm pretty much baffled, any help appreciated.我很困惑,任何帮助表示赞赏。 Thanks.谢谢。

TLDR; TLDR; Confirm jwt.secret is actually being set确认jwt.secret实际上正在设置

I had this same issue, in my case it was caused because the jwt.secret was not being read correctly, when starting Puma via systemd .我遇到了同样的问题,在我的情况下,这是因为在通过systemd启动 Puma 时jwt.secret没有被正确读取。

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

For some reason, on the remote server, when launching via systemd service, env['JWT_SECRET_KEY'] was empty.出于某种原因,在远程服务器上,通过systemd服务启动时, env['JWT_SECRET_KEY']为空。 However, when starting Puma manually, it worked fine.但是,当手动启动 Puma 时,它运行良好。

I found this out, by hard coding a string as the secret.我通过硬编码一个字符串作为秘密发现了这一点。 Suddenly it worked.突然它起作用了。

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 

If jwt.secret is empty, it will still generate an auth token for whatever reason.如果jwt.secret为空,它仍然会出于任何原因生成一个auth token Like you this threw me off, as it made me assume my setup was correct.像你一样,这让我失望,因为它让我认为我的设置是正确的。


To test if you're running into a similar issue, temporarily hardcode gibberish as the secret.要测试您是否遇到类似问题,请暂时将乱码硬编码为秘密。 If that works, then you're on the right track如果那行得通,那么你就在正确的轨道上

Obviously you should not hard code the string, but rather look into and confirm that your secret is being fed correctly into the above config.显然,您不应该对字符串进行硬编码,而应该查看并确认您的密码是否正确输入到上述配置中。

For me that meant specifying an EnvironmentFile in the systemd service configuration which contains key=value pairs (much like a dotenv file).对我来说,这意味着在systemd服务配置中指定一个EnvironmentFile ,其中包含key=value对(很像dotenv文件)。

This question matched my issue but led me to a different answer per this question: ruby on rails: heroku: Missing `secret_key_base` for 'production' environment这个问题符合我的问题,但让我对这个问题给出了不同的答案: ruby on rails: heroku: Missing `secret_key_base` for 'production' environment

For others getting this issue - Check to see if you are using Rails.application.secret_key_base (and not Rails.application.secrets.secret_key_base)对于其他遇到此问题的人 - 检查您是否使用 Rails.application.secret_key_base(而不是 Rails.application.secrets.secret_key_base)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM