5

我已经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]=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

似乎我也暴露了 Authorization 标头:

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

我很困惑,任何帮助表示赞赏。谢谢。

4

2 回答 2

10

TLDR; Confirm jwt.secret is actually being set

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.

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. However, when starting Puma manually, it worked fine.

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. 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).

于 2020-11-24T02:51:28.553 回答
1

这个问题与我的问题相匹配,但根据这个问题让我得到了不同的答案:ruby on rails: heroku: Missing `secret_key_base` for 'production' environment

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

于 2021-01-13T03:07:13.880 回答