我的会话变量不会更新(Ruby on Rails)

时间:2017-02-15 15:13:03

标签: ruby-on-rails session model-view-controller session-variables

我是Ruby on Rails的新手,我试图了解基础知识。 我的应用程序遵循MVC框架,我试图从我的控制器更新会话变量,然后从我的视图中访问它。

这是我的控制器中的代码(这是我更新变量的唯一地方):

def testLogin_method
  if(!session[:loggedIn])
    session[:loggedIn] = true;
  else
    session[:loggedIn] = false;
    redirect_to(static_pages_login_url);
  end
end

helper_method :testLogin_method

当我使用javascript:

点击视图中的登录按钮时,我会调用此方法
function login(){
  <% testLogin_method %>
}

我在退出时打电话给你:

<li><%= link_to raw('<span class="glyphicon glyphicon-log-out"></span> Log out'), :controller => "static_pages", :action => "testLogin_method" %></li>

我的问题是,当我退出时,应用程序会重定向到登录页面,但会话[:loggedIn]保持为true。我如何保持虚假?

编辑:如何将变量会话从true切换为false?登录/注销仅适用于上下文,我不想实际进行身份验证。

P.S。我没有使用Gem Devise,因为我只想了解会话变量的工作原理,这只是一个例子。

2 个答案:

答案 0 :(得分:1)

你的javascript方法有效吗?

因为这不是帮助者的工作方式。它会在呈现页面时调用testLogin_method,而不是在javascript执行时调用。检查渲染JS的来源

在服务器端使用帮助程序来帮助呈现页面。在客户端,您必须从javascript到testLogin_method

进行ajax调用

答案 1 :(得分:0)

如果您想要一个关于如何使用会话的合适示例,请考虑以下示例:

# config/routes.rb
resource :session, only: [:new, :create, :destroy]

# app/models/user.rb
class User < ApplicationRecord
  has_secure_password
end

 # app/helpers/session_helper.rb
module SessionHelper
  def current_user
    @current_user ||= User.find(session[:user_id]) if session[:user_id]
  end

  def user_signed_in?
    current_user.is_a?(User)
  end
end

# app/controllers/session_controller.rb
class SessionController < ApplicationController

  def new
  end

  def create
    reset_session
    @user = User.find_by(params[:email])
    if @user.try(:authenticate, params[:password])
      session[:user_id] = @user.id
      redirect_to :root, success: 'You have been signed in.'
    else
      render :new, error: 'Wrong email or password.'
    end
  end

  def destroy
    reset_session
    flash[:success] = 'You have been signed out.' 
    respond_to do |f|
      f.html { redirect_to :root }
      f.json { head :ok } 
    end
  end
end

这是最简单的基于会话的身份验证系统。用户可以通过POST /session登录,然后通过DELETE /session登录。

当我们将用户注销时,我们调用reset_session会使整个会话无效 - 阻止会话固定攻击。

如果我们想通过javascript签署用户,我们会向DELETE /session发送ajax请求。

<%= button_to session_path, id: 'logout', method: :delete, remote: { true , type: 'json' } do %>
  <span class="glyphicon glyphicon-log-out"></span> Log out
<% end %>

然后我们设置一个ajax监听器来重新加载页面:

$(document).on('ajax:success', '#logout', function(){
  Turbolinks.clearCache();
  Turbolinks.visit(location.toString());
});

您可以更新页面以更改登录和注销之间的状态 - 但更好的解决方案是刷新缓存并重新加载页面。否则,您的登录/退出处理程序必须跟踪页面上的任何if user_signed_in?类型条件。