2011-09-08 23 views
8

Tôi có một ứng dụng web là một phần Rails và một phần Backbone. Một số thứ như hệ thống bình luận mà tôi đã triển khai được viết chủ yếu bằng Javascript ở phía máy khách. Phần cuối của Rails chỉ xử lý sự kiên trì bằng cách chuyển JSON qua lại.Làm cách nào để quản lý phiên người dùng hiện tại ở phía máy khách?

Khi tôi hiển thị các trang từ máy chủ, hãy xử lý những người được xem những gì dễ dàng. Tôi có thể nói những điều như

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

Và đó sẽ chỉ làm cho liên kết để xóa một bình luận đặc biệt nếu người dùng hiện nay là tác giả của nhận xét. Không vấn đề gì.

Tuy nhiên, giờ tôi đang hiển thị nhận xét ở phía máy khách bằng cách sử dụng JavaScript templates (được lưu trong bộ nhớ cache afaik), tôi không có quyền truy cập vào current_user. Tôi không thể biết liệu người dùng hiện đang sử dụng ứng dụng của tôi có phải là tác giả của nhận xét hay không vì vậy tôi không thể kiểm soát nội dung anh ta xem.

Chắc chắn, anh ấy sẽ không thể xóa nhận xét theo cách này vì tôi cũng cho phép trên máy chủ nhưng tôi không muốn hiển thị liên kết ở vị trí đầu tiên.

Tôi làm cách nào để thực hiện việc này?

Tôi muốn một số liên kết đến các tài nguyên về chủ đề này cũng như câu trả lời vì tôi dường như không tìm thấy bất kỳ điều gì, mặc dù có vẻ như đây là một chủ đề cần được đề cập trong vô số blog.

Trả lời

7

Tôi thích sử dụng phương pháp sau đây.

Thứ nhất, trong cách bố trí của bạn, tạo ra trên server-side, truyền dữ liệu hiện tại của người dùng mà bạn sẽ cần phải đứng về phía khách hàng:

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

Nó sẽ có thể truy cập trong các mẫu EJS của bạn. Bây giờ trong mẫu, bạn có thể thực hiện việc kiểm tra tương tự như trên server-side:

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

Phương pháp này có được lưu lại để sử dụng không? Người dùng có thể thay đổi id của người dùng hiện tại – ecleel

+0

Nó an toàn để sử dụng, miễn là bạn cũng có bảo vệ phía máy chủ tại chỗ, để ngay cả khi Người dùng thay đổi ID và cố gắng nhấn xóa, anh ta sẽ nhận được lỗi trái phép 401. Hiển thị và không hiển thị nút xóa là thuận tiện cho người dùng, chứ không phải bảo mật. – AwDogsGo2Heaven

0

Ryan Bates mô tả một thực tế phổ biến cho trường hợp đó, hãy để tôi giải thích. Nó giúp với Dynamic Page Caching, khi bạn sử dụng bộ nhớ đệm trang, nhưng cần phải nhận được một cái gì đó từ các serverside và xử lý nó.

Sắp sửa hiển thị trang mà không có liên kết "Xóa", sau đó nhận yêu cầu kiểm tra xem phiên người dùng hay không và gán kết quả cho biến.

Một trong thực hiện, một chút sâu hơn:

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

Sau đó xử lý các kết quả và ẩn/hiển thị bình luận divs.

+0

Làm nhiều hơn javascript nhiều như bạn có thể, suy nghĩ về phía máy chủ là "nhà cung cấp API" chủ yếu – Anatoly

+0

Có thực sự không phải là một mô hình tốt hơn điều này? Ví dụ: nếu có hàng trăm nhận xét trên trang, thì mỗi lần tải trang sẽ chỉ xuất hiện ở máy chủ. – JofoCodin

+0

đúng, không có cách nào tốt để kiểm tra quyền cho mỗi nhận xét bằng cách tìm nạp hàng trăm lần phía máy chủ. Bạn có thể thử tìm nạp JSON với một cấu trúc 'comments': {id: '1', permission: true} và phát triển một logic dựa trên cấu trúc dữ liệu JSON – Anatoly

2

Điều này đôi khi được gọi là Cá nhân hóa phía máy khách. Nó liên quan đến việc sử dụng các lớp css để ẩn và hiển thị các phần tử chắc chắn dựa trên một giá trị mà javascript nhận được từ một cookie hoặc một yêu cầu ajax.

Tôi thích đặt trạng thái người dùng, tên và dữ liệu khóa khác trong cookie được đặt trong một phần mềm trung gian giá kết thúc tốt nhất lớp lưu trong bộ nhớ cache. Bằng cách này, logic cho phiên người dùng có thể được phân lập từ dữ liệu được lưu trong bộ nhớ cache. Sau đó, tôi sử dụng javascript để đọc cookie này và thay đổi trang nếu cần. Trong trường hợp của ví dụ nhận xét mà bạn đưa ra, tôi sẽ hiển thị từng nhận xét với thông báo ID (hoặc chỉ là id, nếu bạn không quan tâm đến các tác động bảo mật) trong thuộc tính dữ liệu, như vậy:

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

và lưu trữ id của nhận xét của người dùng trong cookie nói trên. Sau đó, javascript đọc cookie và tìm tất cả các nhận xét với các id đó và hiển thị liên kết 'xóa' cho chúng.

Một vấn đề phổ biến với cách tiếp cận này liên quan đến những gì xảy ra khi cookie tràn, như sẽ xảy ra trong ví dụ này với một người bình luận đầy đủ. Cách tiếp cận khác là sử dụng ajax để tìm nạp dữ liệu JSON có liên quan của người dùng, sau đó lưu vào bộ nhớ cache trong bộ nhớ cục bộ.Tôi muốn kết hợp điều đó với việc giữ một phiên bản dữ liệu JSON của người dùng trong một cookie có thể được cập nhật ở phía máy chủ với các cuộc gọi lại after_save và các chiến lược hết hạn bộ nhớ cache khác. Javascript sau đó chỉ cần so sánh trạng thái của JSON của người dùng được tìm thấy trong bộ nhớ cục bộ với phiên bản trong cookie và làm mới JSON này thông qua yêu cầu ajax khi nó cũ.

Đối với một số lời khuyên thêm về Client Side Personalization, xem bài này trong mục "phía khách hàng bộ nhớ cache cá nhân hóa": http://www.tumblr.com/tagged/caching

và một này: http://pivotallabs.com/users/nick/blog/articles/297-making-rails-wicked-fast-pagecaching-highly-personalized-web-pages

Các vấn đề liên quan