繁体   English   中英

如何在客户端管理当前用户会话?

[英]How do I manage the current user session on the client side?

我有一个Web应用程序,它是Rails和部分Backbone的一部分。 我实现的评论系统等一些东西主要是在客户端的Javascript中编写的。 Rails后端只是通过来回传递JSON来处理持久性。

当我从服务器渲染页面时,处理谁可以看到什么是容易的。 我可以说像

<li class="comment">
  <span class="comment_text"><%= @comment.text %></span>
  <% if user_signed_in? and current_user == @comment.author %>
    <a class="delete" href="some delete url">Delete Comment</a>
  <% end %>
</li>

如果当前用户是评论的作者,那只会呈现删除特定评论的链接。 没问题。

但是,现在我在客户端使用JavaScript模板 (缓存为afaik)呈现注释,我无法访问current_user 我不知道当前使用我的应用程序的用户是否是评论的作者,所以我无法控制他看到的内容。

当然,他无法以任何方式删除评论,因为我也在服务器上授权,但我宁愿不首先显示链接。

我怎么能做到这一点?

我喜欢这个主题的资源和答案的一些链接,因为我似乎找不到任何,即使在我看来这是一个应该在无数博客中涵盖的主题。

我更喜欢使用以下方法。

首先,在您的布局中,在服务器端生成,传递您在客户端需要的当前用户数据:

<script type="text/javascript">
    window.currentUser = {
        id : "<%=current_user.id%>"
    }
</script>

它可以在您的EJS模板中访问。 现在在模板中,您可以进行与服务器端相同的检查:

<% if (window.currentUser && window.currnetUser.id == comment.author.id) { %>
    <a class="delete" href="some delete url">Delete Comment</a>
<% } %>

这有时称为客户端个性化。 它涉及使用css类来隐藏和显示基于javascript从cookie或ajax请求获取的值的元素。

我更喜欢在包装缓存层的机架中间件中设置的cookie中设置用户状态,名称和其他关键数据。 这样,用户会话的逻辑可以与缓存数据隔离。 然后我使用javascript来读取此cookie并根据需要更改页面。 对于您给出的注释示例,我会在数据属性中使用其ID的摘要(或者只是id,如果您不关心安全隐患)来呈现每个注释,如下所示:

<div class="comment_203948">...</div>

并将用户评论的ID存储在上述cookie中。 然后javascript读取cookie并查找带有这些ID的所有注释,并显示它们的“删除”链接。

这种方法的一个常见问题涉及当cookie溢出时会发生什么,就像在这个例子中用一个多产的评论者所发生的那样。 另一种方法是使用ajax获取用户的相关JSON数据,然后将其缓存在本地存储中。 我喜欢将它与将用户的JSON数据版本保存在一个cookie中相结合,该cookie可以在服务器端使用after_save回调和其他缓存到期策略进行更新。 然后,Javascript简单地将本地存储中找到的用户JSON的状态与cookie中的版本进行比较,并在过时时通过ajax请求刷新此JSON。

有关客户端个性化的一些进一步提示,请参阅“客户端缓存个性化”下的这篇文章: http//www.tumblr.com/tagged/caching

这一个: http//pivotallabs.com/users/nick/blog/articles/297-making-rails-wicked-fast-pagecaching-highly-personalized-web-pages

Ryan Bates描述了这种情况的常见做法,让我解释一下。 当您使用页面缓存时,它有助于动态页面缓存,但需要从服务器端获取并处理它。

即将呈现没有“删除”链接的页面,然后获取检查用户会话是否的请求,并将结果分配给变量。

其中一个实现,更深入一点:

   # controller
   class UserSessionController < ActionController::Base
     skip_before_filter :require_user, :only => [:new, :create, :user_sign_in]

     def user_sign_in
       if current_user
         render :text => 'success'
       else
         render :text => 'false', :status => 403
       end
     end
   end


   class CommentsController < ApplicationController
     def has_right
       current_user == @comment.author
     end
   end


   # view
   <% javascript_tag do %>
    var a = $.getJSON('/user_session/user_sign_in', function(data){
        console.log(data)
    });

   <% end %>

然后处理结果并隐藏/显示注释div。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM