2011-09-08 2 views
8

Ho un'app Web che è in parte Rails e parte Backbone. Alcune cose come un sistema di commenti che ho implementato sono scritte principalmente in Javascript sul lato client. Il backend di Rails gestisce semplicemente la persistenza passando JSON avanti e indietro.Come gestisco la sessione utente corrente dal lato client?

Quando eseguo il rendering delle pagine dal server, gestisco chi riesce a vedere cosa è facile. Posso dire cose come

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

E che renderà solo il link per cancellare un commento particolare se l'utente corrente è l'autore del commento. Nessun problema.

Tuttavia, ora che sto rendendo commenti sul lato client utilizzando JavaScript templates (che sono memorizzati nella cache afaik), non ho accesso a current_user. Non riesco a capire se l'utente che sta usando la mia app sia autore o meno del commento, quindi non posso controllare ciò che vede.

Certo, non sarà in grado di eliminare il commento in entrambi i casi perché anch'io autorizzo sul server, ma preferisco non mostrare hin il collegamento in primo luogo.

Come posso realizzare questo?

Mi piacerebbe avere alcuni collegamenti alle risorse su questo argomento e risposte perché non riesco a trovarlo, anche se a me sembra che questo sia un argomento che avrebbe dovuto essere trattato in innumerevoli blog.

risposta

7

Io preferisco usare l'approccio seguito.

In primo luogo, nel layout, generato sul lato server, passare i dati dell'utente corrente che avrete bisogno sul lato client:

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

sarà accessibile nei modelli EJS. Ora, nel modello, è possibile effettuare lo stesso controllo come sul lato server:

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

Questo approccio è stato salvato? L'utente può modificare l'ID di currentUser – ecleel

+0

È sicuro da usare, purché si disponga anche di protezioni laterali del server, in modo che anche se l'utente cambia l'ID e preme eliminare, riceverà un errore non autorizzato 401. Mostrare e non mostrare il pulsante Elimina è per comodità dell'utente, non per sicurezza. – AwDogsGo2Heaven

0

Ryan Bates descrive una pratica comune per quel caso, lasciatemi spiegare. È utile con Dynamic Page Caching, quando si utilizza la memorizzazione nella cache della pagina, ma è necessario ottenere qualcosa dal lato server e gestirlo.

Sta per eseguire il rendering della pagina senza collegamento "Elimina", quindi ottenere una richiesta per verificare se la sessione utente o meno e assegnare il risultato a una variabile.

Uno di realizzazione, un po 'più profondo:

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

quindi gestire il risultato e Mostra/Nascondi commenti div.

+0

Fate più javascript per quanto è possibile, pensare a server-side come "fornitore di API" per lo più – Anatoly

+0

Ci non è proprio un modello migliore di Questo? Se, ad esempio, ci sono centinaia di commenti sulla pagina, allora ogni carico di pagina sta andando a sbattere contro il server. – JofoCodin

+0

esatto, non esiste un buon modo per controllare l'autorizzazione per ogni commento recuperando centinaia di volte sul lato server. Puoi provare a recuperare JSON con una struttura 'commenti': {id: '1', permesso: true} e sviluppare una logica basata sulla struttura dati JSON – Anatoly

2

Questo è talvolta chiamato Personalizzazione lato client. Implica l'uso di classi CSS per nascondere e mostrare certamente elementi basati su un valore che javascript ottiene da un cookie o da una richiesta Ajax.

Preferisco impostare lo stato utente, il nome e altri dati chiave in un cookie impostato in un middleware rack che avvolge il livello di memorizzazione nella cache. In questo modo, la logica per la sessione utente può essere isolata dai dati memorizzati nella cache. Quindi uso javascript per leggere questo cookie e modificare la pagina secondo necessità. Nel caso dell'esempio di commenti che hai fornito, eseguivo il rendering di ogni commento con un digest del suo ID (o semplicemente l'id, se non ti preoccupi delle implicazioni sulla sicurezza) in un attributo dati, ad esempio:

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

e memorizzare gli ID dei commenti di un utente nel cookie di cui sopra. Quindi javascript legge il cookie e trova tutti i commenti con quegli id, e mostra il link 'cancella' per loro.

Un problema comune con questo approccio riguarda ciò che accade quando il cookie trabocca, come accadrebbe in questo esempio con un commentatore prolifico. Un altro approccio è usare ajax per recuperare i dati JSON rilevanti dell'utente, quindi per memorizzarli nella memoria locale.Mi piace combinarlo con la conservazione di una versione dei dati JSON dell'utente in un cookie che può essere aggiornato sul lato server con callback after_save e altre strategie di scadenza cache. Javascript quindi confronta semplicemente lo stato del JSON dell'utente trovato nella memoria locale con la versione nel cookie e aggiorna questo JSON tramite una richiesta Ajax quando è inattivo.

Per alcuni ulteriori suggerimenti su lato client Personalizzazione, vedi questo post sotto "cache personalizzazione lato client": http://www.tumblr.com/tagged/caching

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