Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a web app which is part Rails and part Backbone. Some things such as a commenting system I have implemented are written mostly in Javascript on the client side. The Rails backend simply handles persistance by passing JSON back and forth.

When I render pages from the server, handling who gets to see what is easy. I can say things such as

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

And that will only render the link to delete a particular comment if the current user is the comment's author. No problem.

However, now that I'm rendering comments on the client side using JavaScript templates (which are cached afaik), I don't have access to current_user. I can't tell if the user currently using my app is the author of the comment or not so I can't control what he gets to see.

Sure, he won't be able to delete the comment either way because I authorize on the server as well but I'd rather not show hin the link in the first place.

How can I accomplish this?

I'd love some links to resources on this topic as well as answers because I can't seem to find any, even though it seems to me like this is a topic that should have been covered in countless blogs.

like image 259
David Tuite Avatar asked Sep 08 '11 09:09

David Tuite


People also ask

What is client side session?

Client-side sessions use cookies and cryptographic techniques to maintain state without storing as much data on the server. When presenting a dynamic web page, the server sends the current state data to the client (web browser) in the form of a cookie. The client saves the cookie in memory or on disk.

What is user session management?

Session management. A single user that logs in multiple times (for example, from different machines) has multiple WebSEAL session IDs and a credential for each session. The user session ID is based on the WebSEAL session ID (there exists a one-to-one mapping between the two keys).

How can you track the user session?

There are several ways to track user sessions including cookies, URL rewriting, and hidden form fields. If session tracking is not used, request 2 is treated as a new request without the server recognizing that it is from the same user.


2 Answers

I prefer using following approach.

First, in your layout, generated on server-side, pass current user's data that you'll need on client side:

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

It will be accessible in your EJS templates. Now in template, you can make the same check as on server-side:

<% if (window.currentUser && window.currnetUser.id == comment.author.id) { %>
    <a class="delete" href="some delete url">Delete Comment</a>
<% } %>
like image 159
daeq Avatar answered Oct 23 '22 02:10

daeq


This is sometimes called Client Side Personalization. It involves using css classes to hide and show certainly elements based on a value that javascript gets from a cookie or an ajax request.

I prefer setting user state, name, and other key data in a cookie that is set in a rack middleware that wraps the caching layer. This way, the logic for user session can be isolated from cached data. Then I use javascript to read this cookie and alter the page as needed. In the case of the comments example that you gave, I would render each comment with a digest of its ID (or just the id, if you aren't concerned about the security implications) in a data attribute, like so:

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

and store the ids of a user's comments in the aforementioned cookie. Then javascript reads the cookie and finds all comments with those ids, and shows the 'delete' link for them.

A common problem with this approach involves what happens when the cookie overflows, as would happen in this example with a prolific commenter. Another approach is to use ajax to fetch the user's relevant JSON data, then to cache that in local storage. I like to combine that with keeping a version of the user's JSON data in a cookie that can be updated on the server-side with after_save callbacks and other cache-expiry strategies. Javascript then simply compares the state of the user's JSON found in local storage with the version in the cookie, and refreshes this JSON via an ajax request when it's stale.

For some further tips on Client Side Personalization, see this post under "client side cache personalization": http://www.tumblr.com/tagged/caching

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

like image 38
alegscogs Avatar answered Oct 23 '22 03:10

alegscogs