2011-09-08 9 views
8

私は、一部のRailsで、一部がBackboneのWebアプリケーションを持っています。私が実装したコメントシステムのようなものは、ほとんどがクライアント側の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にアクセスできません。私は、現在私のアプリを使っているユーザーがコメントの作者であるかどうかを知ることができないので、彼が見たいものを制御することはできません。

確かに、私はサーバーでも権限を与えているので、彼はコメントを削除することはできませんが、まず最初にリンクを表示しないでください。

どうすればこの問題を解決できますか?

私はこれが無数のブログでカバーされていたはずのトピックであるように思われるにもかかわらず、私は何かを見つけることができないため、このトピックのリソースへのリンクと回答が大好きです。

答えて

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

Ryan Batesはこのケースの一般的な慣行について説明します。 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

あなたは、「APIプロバイダ」として、サーバー側について考えることができるように、よりJavaScriptなどの多くを行うほとんど – Anatoly

+0

より良いパターンは本当にありませんこの?たとえば、ページに何百ものコメントがある場合、すべてのページ負荷はサーバーで叩かれるだけです。 – JofoCodin

+0

そうですね、サーバーサイドの何百回もフェッチすることで、すべてのコメントのパーミッションをチェックする良い方法はありません。 JSONを構造体 'comments':{id: '1'、permission:true}で取得し、JSONデータ構造に基づいてロジックを開発することができます – Anatoly

2

これは、クライアント側のパーソナライゼーションとも呼ばれます。これは、cssクラスを使用して、javascriptがcookieまたはajaxリクエストから取得する値に基づいて要素を隠して確実に表示することを伴います。

キャッシングレイヤーをラップするラックミドルウェアに設定されているクッキー内のユーザー状態、名前、およびその他のキーデータを設定することをお勧めします。このようにして、ユーザーセッションのロジックをキャッシュデータから分離することができます。次に、私はこのクッキーを読んで、必要に応じてページを変更するためにjavascriptを使います。あなたが与えたコメントの例では、データ属性にIDのダイジェスト(またはセキュリティの意味が気にならない場合はIDのみ)を次のようにレンダリングします。

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

上記のCookieにユーザーのコメントのIDを格納します。その後、javascriptはCookieを読み取り、それらのIDを持つすべてのコメントを見つけ、それらのための '削除'リンクを表示します。

このアプローチの一般的な問題は、この例では多量のコメント作成者が発生するように、Cookieがオーバーフローしたときに何が起こるかということです。もう1つの方法は、ajaxを使用してユーザーの関連するJSONデータを取得し、ローカルのストレージにキャッシュします。私はこれを、ユーザーのJSONデータのバージョンを、after_saveコールバックおよびその他のキャッシュ有効期限戦略を使用してサーバー側で更新できるCookieに保存することと組み合わせることを好みます。 Javascriptは、ローカルストレージにあるユーザーのJSONの状態をクッキー内のバージョンと単純に比較し、古いときにこのJSONをajaxリクエストで更新します。 http://www.tumblr.com/tagged/caching

と、この1: http://pivotallabs.com/users/nick/blog/articles/297-making-rails-wicked-fast-pagecaching-highly-personalized-web-pages

関連する問題