“No verification key available” when attempting to access API secured by Devise JWT

狂风中的少年 提交于 2021-01-01 04:19:39

问题


I have the gem devise-jwt installed. 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.

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

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.


回答1:


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



来源:https://stackoverflow.com/questions/64923974/no-verification-key-available-when-attempting-to-access-api-secured-by-devise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!