【问题标题】:Rails 6 Session Data Not PersistingRails 6 会话数据不持久
【发布时间】:2021-09-23 18:55:43
【问题描述】:

我已经为此奋斗了大约 24 小时,但我在搜索中没有找到任何解决方案。

我的问题是我的会话数据没有保留,我无法登录到我的应用程序。一切都在开发模式下工作,但还没有在生产模式下工作。我正在使用托管在 Heroku 上的 Rails 6 Api 和 React 前端。我可以成功地进行 api 调用,找到用户并使用它们登录(我使用“puts”来帮助我在该实例上记录会话。此时会话哈希有一个 session_id 和 user_id):

def login!
    session[:user_id] = @user.id
    puts "login_session: #{session.to_hash}"
end

在此之后,应用会根据用户授权重定向到用户页面或管理页面。

当重定向发生时,用户或管理页面调用api查看用户是否被授权使用:

def logged_in?
    puts "logged_in_session: #{session.to_hash}"
    !!session[:user_id]
end

会话为空。这是我的会话控制器:

class SessionsController < ApplicationController

def create
    @user = User.find_by(email: session_params[:email])
    puts @user.inspect
    if @user && @user.authenticate(session_params[:password])
        
      login!
      render json: {
        logged_in: true,
        user: UserSerializer.new(@user)
      }
    else
      render json: { 
        status: 401,
        errors: ['no such user', 'verify credentials and try again or signup']
      }
    end
end


def is_logged_in?
    if logged_in? && current_user
      render json: {
        logged_in: true,
        user: UserSerializer.new(current_user)
      }
    else
      render json: {
        logged_in: false,
        message: 'no such user or you need to login'
      }
    end
end

def is_authorized_user?
    
    user = User.find(params[:user_id][:id])
    
    if user == current_user
        render json: {
            authorized: true
        }
    else
        render json:{
            authorized: false
        }
    end
end


def destroy
    logout!
    render json: {
      status: 200,
      logged_out: true
    }
end

def omniauth
  @user = User.from_omniauth(auth)
  @user.save
  login!
  render json: UserSerializer.new(@user)
end

private

def session_params
    params.require(:user).permit(:username, :email, :password)
end

def auth
    
    request.env['omniauth.auth']
end

谁能给我指出正确的方向??

谢谢

【问题讨论】:

  • 代码对我来说看起来不错。我在这里可能错了,但看起来您将控制器用作 API 端点(由于 JSON 响应)。浏览器是否有可能一开始就从未存储过 cookie(会话)?可能是因为 API 端点位于不同的(子)域上,或者只是因为 Javascript 处理它的方式。
  • 谢谢,是的,我将它用作 API。这可能是一个愚蠢的问题,但我必须以不同于开发环境的方式处理 cookie 吗?
  • 我不确定。通过我们的 API 端点,我们使用用户通过 API 调用发送的 API 密钥。所以在认证之后,控制器会在 JSON 中返回一个 API 密钥,然后由 JavaScript 存储在一个 cookie 中。然后,在随后的每个 API 调用中,它们的 API 密钥都通过 cookie 包含在内。这很麻烦,所以除非您正在编写移动应用程序,否则您可能只想让登录表单同步。

标签: ruby-on-rails heroku production


【解决方案1】:

我会验证以下内容:

  1. 首次通过身份验证时,来自端点的响应是否包含 cookie 数据?
  2. 检查浏览器中的 cookie 存储(您可以使用一些扩展程序来简化此操作)并验证域名是否匹配以及 cookie 中的内容是否符合您的预期。
  3. 您可以将 cookie ID 与会话存储中的 ID 交叉引用(取决于您选择的存储位置)。
  4. 能否验证会话存储中的 cookie 内容 (user_id) 和会话内容。
  5. 确保在身份验证后的下一个请求中发送 cookie 数据(检查浏览器中开发工具的网络选项卡中的请求标头)。

这一切都假设您正在使用浏览器与此 JSON 端点通信。 API 通常不使用 cookie,因为它是浏览器的东西。替代身份验证机制可能是在身份验证时生成的可用于后续请求的短期令牌(例如 JWT)。

【讨论】:

  • 谢谢!我已经能够验证响应不包括 cookie 数据。在我的开发环境中包含 cookie,但在 Prod 中没有。我该如何解决这个问题??
  • 我现在将检查每个环境的会话/cookie 配置。检查config/environment.rbconfig/environment/production.rb 文件,因为有几个选项与如何处理cookie 和会话有关。浏览这些文件的 git 历史记录或在另一个目录中创建一个新的 Rails 应用程序并与你的进行比较可能会有所帮助。
【解决方案2】:

快速更新:我能够在响应中获得“Set-Cookie:_session_id=...”,但由于“SameSite=lax”属性而被阻止。

我认为我需要更改为 SameSite = none,但我不确定是否要这样做。

有什么建议吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 2015-08-16
    • 2011-07-05
    • 2019-04-20
    • 2019-03-14
    • 2012-11-20
    • 2012-03-17
    相关资源
    最近更新 更多