2011-09-08 116 views
8

我有一個網絡應用程序是部分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 templates(這是緩存的afaik)在客戶端渲染評論,我無權訪問current_user。我無法分辨目前使用我的應用程序的用戶是否是評論的作者,因此我無法控制他看到的內容。

當然,他將無法以任何方式刪除評論,因爲我也在服務器上進行了授權,但我寧願不首先顯示hin鏈接。

我該如何做到這一點?

我喜歡關於這個主題的資源以及答案的一些鏈接,因爲我似乎無法找到任何東西,即使在我看來,這是一個本應該在無數博客中討論的主題。

回答

7

我喜歡用下面的方法。

首先,在你的佈局,在服務器端生成,傳遞,你需要在客戶端當前用戶的數據:

<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> 
<% } %> 
+1

此方法是否可以保存?用戶可以更改當前用戶的ID – ecleel

+0

使用安全,只要你也有服務器端保護,即使用戶更改ID,並嘗試按刪除,他將得到401未經授權的錯誤。顯示並不顯示刪除按鈕是爲了用戶方便,而不是安全。 – AwDogsGo2Heaven

0

瑞恩貝茨描述了這種情況下的一種常見做法,讓我解釋一下。 當你使用頁面緩存時,它可以幫助Dynamic Page Caching,但需要從服務器端獲取並處理它。

即將呈現沒有「刪除」鏈接的頁面,然後獲取請求以檢查用戶會話與否,並將結果分配給變量。

一個實現的,一個稍微深一點:

# 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。

+0

做更多的JavaScript,就像你可以考慮服務器端爲「API提供者」大多是 – Anatoly

+0

這確實並不比一個更好的模式這個?例如,如果頁面上有數百條評論,那麼每個頁面加載只會在服務器上爆炸。 – JofoCodin

+0

沒錯,沒有這麼好的方法來檢查服務器端數百次的每條評論的權限。您可以嘗試使用結構'comments'獲取JSON:{id:'1',permission:true}並開發基於JSON數據結構的邏輯 – Anatoly

2

這有時稱爲客戶端個性化。它涉及使用css類來隱藏和顯示基於javascript從cookie或ajax請求獲取的值的元素。

我更喜歡在包裝高速緩存層的機架中間件中設置的cookie中設置用戶狀態,名稱和其他關鍵數據。這樣,用戶會話的邏輯可以與緩存數據隔離。然後我使用javascript來讀取這個cookie並根據需要改變頁面。在您給出的評論示例的情況下,我會在數據屬性中使用其ID的摘要(或者只是ID,如果您不擔心安全影響)呈現每條評論,如下所示:

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

並在上述cookie中存儲用戶評論的ID。然後JavaScript讀取cookie並用這些ID查找所有註釋,並顯示它們的「刪除」鏈接。

這種方法的一個常見問題涉及當cookie溢出時會發生什麼,就像在這個例子中發生的多產評論者那樣。另一種方法是使用ajax獲取用戶的相關JSON數據,然後將其緩存到本地存儲中。我喜歡將這一點與用戶的JSON數據版本保存在cookie中,並使用after_save回調和其他緩存過期策略在服務器端進行更新。然後,JavaScript簡單地比較本地存儲中發現的用戶JSON的狀態與Cookie中的版本,並在舊的JSON過期時通過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