Rails API + Devise + JWT 上的注销问题
Problem with the logout on Rails API + Devise + JWT
我正在构建 Rails API。我所有的设计路线都工作正常,其中一条:logout.
我遵循了这个教程:https://jameschambers.co.uk/rails-api
我已经尝试了一些东西,例如:
- 尝试了 api/logout.json 路线
- 试图将 rb #111 更改为:config.skip_session_storage = [:http_auth, :params_auth] ( config/initializers/devise.rb )
- 试图为 : config.sign_out_via = :get ( config/initializers/devise.rb )
更改 rb #280
我正在向此地址发送删除请求:localhost:3000/api/logout,带有 JWT/Bearer 令牌。
错误
"status": 500,
"error": "Internal Server Error",
"exception": "#<ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column jwt_denylist.exp does not exist\nLINE 1: ...jwt_denylist\" WHERE \"jwt_denylist\".\"jti\" = AND \"jwt_denyl...
rails 航线
destroy_user_session DELETE /api/logout(.:format) sessions#destroy {:format=>:json}
db/schema.rb
ActiveRecord::Schema.define(version: 2021_09_01_233823) do
create_table "jwt_denylist", force: :cascade do |t|
t.string "jti", null: false
t.datetime "expired_at", null: false
t.index ["jti"], name: "index_jwt_denylist_on_jti"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
app/controllers/sessions_controller.rb
class SessionsController < Devise::SessionsController
private
def respond_with(resource, _opts = {})
render_jsonapi_response(resource)
end
def respond_to_on_destroy
head :no_content
end
end
app/models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:jwt_authenticatable, jwt_revocation_strategy: JwtDenylist
end
config/routes.rb
Rails.application.routes.draw do
default_url_options :host => "http://localhost:3000"
namespace :api, defaults: { format: :json } do
resources :users, only: %w[show]
end
devise_for :users,
defaults: { format: :json },
path: '',
path_names: {
sign_in: 'api/login',
sign_out: 'api/logout',
registration: 'api/signup'
},
controllers: {
sessions: 'sessions',
registrations: 'registrations'
}
end
错误 ERROR: column jwt_denylist.exp does not exist
表示它正在查找 jwt_denylist
table.
上不存在的列 (exp
)
您的架构显示您有一个 expired_at
但没有 exp
列。
从 jwt-denylist gem 它期望的架构 exp
。也许教程已经过时了?以下是 gem 文档的建议:
create_table :jwt_denylist do |t|
t.string :jti, null: false
t.datetime :exp, null: false
end
add_index :jwt_denylist, :jti
所以我会将 :expired_at
列重命名为 :exp
,例如
rails generate migration rename_expired_at_to_exp_on_jwt_denylist
并使更改方法类似于:
def change
rename_column :jwt_denylist, :expired_at, :exp
end
成功了,谢谢梅尔彻!! :)
这就是迁移的样子
class CreateJwtDenylist < ActiveRecord::Migration[6.1]
def change
create_table :jwt_denylist do |t|
t.string :jti, null: false
t.datetime :expired_at, null: false
end
add_index :jwt_denylist, :jti
end
end
这是现在的样子
class CreateJwtDenylist < ActiveRecord::Migration[6.1]
def change
create_table :jwt_denylist do |t|
t.string :jti, null: false
t.datetime :exp, null: false
end
add_index :jwt_denylist, :jti
end
end
我正在构建 Rails API。我所有的设计路线都工作正常,其中一条:logout.
我遵循了这个教程:https://jameschambers.co.uk/rails-api
我已经尝试了一些东西,例如:
- 尝试了 api/logout.json 路线
- 试图将 rb #111 更改为:config.skip_session_storage = [:http_auth, :params_auth] ( config/initializers/devise.rb )
- 试图为 : config.sign_out_via = :get ( config/initializers/devise.rb ) 更改 rb #280
我正在向此地址发送删除请求:localhost:3000/api/logout,带有 JWT/Bearer 令牌。
错误
"status": 500,
"error": "Internal Server Error",
"exception": "#<ActiveRecord::StatementInvalid: PG::UndefinedColumn: ERROR: column jwt_denylist.exp does not exist\nLINE 1: ...jwt_denylist\" WHERE \"jwt_denylist\".\"jti\" = AND \"jwt_denyl...
rails 航线
destroy_user_session DELETE /api/logout(.:format) sessions#destroy {:format=>:json}
db/schema.rb
ActiveRecord::Schema.define(version: 2021_09_01_233823) do
create_table "jwt_denylist", force: :cascade do |t|
t.string "jti", null: false
t.datetime "expired_at", null: false
t.index ["jti"], name: "index_jwt_denylist_on_jti"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
app/controllers/sessions_controller.rb
class SessionsController < Devise::SessionsController
private
def respond_with(resource, _opts = {})
render_jsonapi_response(resource)
end
def respond_to_on_destroy
head :no_content
end
end
app/models/user.rb
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:jwt_authenticatable, jwt_revocation_strategy: JwtDenylist
end
config/routes.rb
Rails.application.routes.draw do
default_url_options :host => "http://localhost:3000"
namespace :api, defaults: { format: :json } do
resources :users, only: %w[show]
end
devise_for :users,
defaults: { format: :json },
path: '',
path_names: {
sign_in: 'api/login',
sign_out: 'api/logout',
registration: 'api/signup'
},
controllers: {
sessions: 'sessions',
registrations: 'registrations'
}
end
错误 ERROR: column jwt_denylist.exp does not exist
表示它正在查找 jwt_denylist
table.
exp
)
您的架构显示您有一个 expired_at
但没有 exp
列。
从 jwt-denylist gem 它期望的架构 exp
。也许教程已经过时了?以下是 gem 文档的建议:
create_table :jwt_denylist do |t|
t.string :jti, null: false
t.datetime :exp, null: false
end
add_index :jwt_denylist, :jti
所以我会将 :expired_at
列重命名为 :exp
,例如
rails generate migration rename_expired_at_to_exp_on_jwt_denylist
并使更改方法类似于:
def change
rename_column :jwt_denylist, :expired_at, :exp
end
成功了,谢谢梅尔彻!! :)
这就是迁移的样子
class CreateJwtDenylist < ActiveRecord::Migration[6.1]
def change
create_table :jwt_denylist do |t|
t.string :jti, null: false
t.datetime :expired_at, null: false
end
add_index :jwt_denylist, :jti
end
end
这是现在的样子
class CreateJwtDenylist < ActiveRecord::Migration[6.1]
def change
create_table :jwt_denylist do |t|
t.string :jti, null: false
t.datetime :exp, null: false
end
add_index :jwt_denylist, :jti
end
end