我有一个新应用程序,正在尝试使用
devise
和 devise-jwt
设置。由于某种原因,我的 authenticate_user!
调用导致错误,因为会话已被禁用:
{"status":500,"error":"Internal Server Error","exception":"ActionDispatch::Request::Session::DisabledSessionError: Your application has sessions disabled. To write to the session you must first configure a session store"
路线:
Rails.application.routes.draw do
namespace :api do
namespace :v1 do
resources :clients, only: [:show]
devise_for :users,
controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations'
}
end
end
end
用户
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable,
:jwt_authenticatable,
jwt_revocation_strategy: JwtDenylist
end
控制器:
class API::V1::Users::SessionsController < Devise::SessionsController
respond_to :json
private
def respond_with(resource, _opts = {})
render json: { message: 'Logged.' }, status: :ok
end
def respond_to_on_destroy
current_user ? log_out_success : log_out_failure
end
def log_out_success
render json: { message: "Logged out." }, status: :ok
end
def log_out_failure
render json: { message: "Logged out failure."}, status: :unauthorized
end
end
class Api::V1::ClientsController < ApplicationController
before_action :authenticate_api_v1_user!
def show
end
end
我还需要做什么?当我向
http://localhost:3000/api/v1/clients/ID
提出请求时,我希望得到的答复是:
=> <html><body>You are being <a href="http://localhost:3000/users/sign_in">redirected</a>.</body></html>%
而不是这个 500 错误。
我在 GitHub 上找到了解决方案:
config.session_store :cookie_store, key: '_interslice_session' config.middleware.use ActionDispatch::Cookies config.middleware.use config.session_store, config.session_options
在rails api_only 上启用会话时要小心。默认情况下,仅限 api 的应用程序禁用会话。
默认情况下,Warden 需要存储会话。您可以简单地将选项 false 添加到 devise.rb 来存储。
config.warden do |manager|
manager.scope_defaults :user, store: false
end
额外:对于想要访问 sidekiq 网络的人,他们必须仅为 sidekiq 路由启用会话。
require 'sidekiq/web'
Sidekiq::Web.use ActionDispatch::Cookies
Sidekiq::Web.use ActionDispatch::Session::CookieStore, key: "_interslice_session"
Rails.application.routes.draw do
# Sidekiq login auth bonus, of course u can improve the secutiry.
Sidekiq::Web.use Rack::Auth::Basic do |username, password|
username == 'username' && password == 'password'
end
mount Sidekiq::Web => "/sidekiq"
end