[Question] How to set a cookie in authentication response?
Closed this issue · 1 comments
joemasilotti commented
I'm building a hybrid app with Turbo and want to set the session cookie when signing in via the API. The client will then pass this cookie to the web view to sign in there.
I've wired up my custom controller via routes but am running into an issue when using #sign_in
from Devise. Here's my controller, the only line that is different is the call to #sign_in
.
module Users
class AuthenticationController < ApiGuard::AuthenticationController
before_action :find_resource, only: [:create]
def create
if resource.authenticate(params[:password])
create_token_and_set_header(resource, resource_name)
sign_in("User", resource) # This line is the only change.
render_success(message: I18n.t("api_guard.authentication.signed_in"))
else
render_error(422, message: I18n.t("api_guard.authentication.invalid_login_credentials"))
end
end
private
def find_resource
self.resource = resource_class.find_by(email: params[:email].downcase.strip) if params[:email].present?
render_error(422, message: I18n.t("api_guard.authentication.invalid_login_credentials")) unless resource
end
end
end
Successfully authenticating raises the following error:
RuntimeError (Could not find a valid mapping for #<User id: 1, email: "joe@masilotti.com", created_at: "2021-03-14 04:34:15.068574000 +0000", updated_at: "2021-03-17 00:03:05.959170000 +0000">):
app/controllers/users/authentication_controller.rb:8:in `create'
Is it not possible to use Devise methods here? I feel like I'm missing something obvious and any help would be greatly appreciated!
joemasilotti commented
Actually, I think I figured it out! They key is the manual mapping of class_name: "User"
in routes.rb
. I also simplified the controller to be only what I need.
# app/controllers/users/authentication_controller.rb
module Users
class AuthenticationController < ApiGuard::AuthenticationController
def create
super
sign_in(resource) if response.ok?
end
end
end
# config/routes.rb
Rails.application.routes.draw do
devise_for :users, class_name: "User"
# ...
scope path: :api do
api_guard_routes for: "users", controller: {
authentication: "users/authentication"
}
end
end