首页 > 解决方案 > 部署到heroku时,Rails在第二次调用时不保留会话

问题描述

我创建了一个 Rails 应用程序,用作 api 应用程序(带有角度前端)。当我尝试在 上创建会话时SessionsController#create,我正在设置session[:user_id]并返回一个用户对象。我的前端应用程序已成功获取此对象并将浏览器重定向到 #/dashboard。 DashboardComponent有一个叫 my 的警卫,SessionsController#logged_in它检查我的 rails 应用程序中的会话。当我在本地运行时,这没有问题。但是,当部署到 Heroku 时,session[:user_id]它是空的。我不确定我做错了什么。我知道这不是 CORS 或 CSRF 问题,因为我的客户端应用程序获取了用户对象(我将其记录到控制台)。

这是我的initializers/session_store.rb

if Rails.env == "production"
  Rails.application.config.session_store :cookie_store, key: "_myapp", domain: "api-app.herokuapp.com"
else
  Rails.application.config.session_store :cookie_store, key: "_myapp"
end

只是为了好玩,这是我的initializers/cors.rb

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins "http://localhost:4200", "https://angular-app.herokuapp.com"
    resource "*", 
      headers: :any, 
      methods: [:get, :post, :put, :patch, :delete, :options, :head], 
      credentials: true
  end
end

SessionsController.rb

class SessionsController < ApplicationController
    include CurrentUserConcern
  
    def create
      user = User
              .find_by(email: params["email"])
              .try(:authenticate, params["password"])
  
      if user
        session[:user_id] = user.id
        render json: user, status: :created
      else
        head :unauthorized
      end
    end
  
    def logged_in
      if @current_user
        render json: @current_user, status: :ok
      else
        head :no_content
      end
    end
  
    def logout
      reset_session
      head :no_content
    end
  end

current_user_concern.rb

module CurrentUserConcern
  extend ActiveSupport::Concern

  included do
    before_action :set_current_user, only: [:logged_in]
  end

  def set_current_user
    puts session[:user_id]
    if session[:user_id]
      @current_user = User.find(session[:user_id])
    end
  end
end

我可以提供任何其他可能有帮助的代码

标签: ruby-on-railsheroku

解决方案


我能够使用自定义域名解决此问题。我将我的 Angular 应用程序设置为使用www.kroe761.com,将我的 api 设置为使用 api.kroe761.com。然后我将我的 session_store 设置为: Rails.application.config.session_store :cookie_store, key: "_myapp", domain: :all, tld_length: 2

因此,显然这个问题与客户端和 api 的域不同有关。我不知道如何在这种情况下配置所有内容(如果您这样做,请为我的启发添加答案),但现在问题已解决。


推荐阅读