2010-03-25 42 views
15

Tôi có ứng dụng ASP.net về cơ bản là màn hình nhập dữ liệu cho quy trình kiểm tra vật lý. Người dùng muốn có thể mở nhiều cửa sổ trình duyệt và đồng thời nhập dữ liệu từ nhiều lần kiểm tra. Lúc đầu, tôi đã sử dụng các phiên dựa trên cookie, và rõ ràng điều này đã bị thổi phồng.Cách ngăn chặn nhiều cửa sổ trình duyệt chia sẻ cùng một phiên trong asp.net

Tôi đã chuyển sang sử dụng các phiên cookie ít hơn, lưu phiên trong URL và trong khi thử nghiệm điều này dường như giải quyết được sự cố. Mỗi cửa sổ/tab trình duyệt có một ID phiên khác nhau và dữ liệu được nhập vào một ID không được nhập vào dữ liệu khác.

Tuy nhiên người dùng của tôi hiệu quả hơn trong việc phá vỡ mọi thứ hơn tôi mong đợi và có vẻ như họ vẫn đang quản lý để có được cùng một phiên giữa các trình duyệt đôi khi. Tôi nghĩ rằng họ đang sao chép/dán địa chỉ từ một tab này sang tab khác để mở ứng dụng, nhưng tôi chưa thể xác minh điều này (chúng ở một vị trí khác để tôi không thể dễ dàng hỏi chúng).

Ngoài việc yêu cầu họ không sao chép và dán hoặc thuyết phục họ chỉ nhập từng tài khoản một, làm cách nào để ngăn tình trạng này xảy ra?

+1

Tôi có thể sai (do đó không đặt câu trả lời này), nhưng tôi tin rằng đây là hạn chế trình duyệt. Ngoài phương pháp cookieless mà bạn đã thử, tôi không nghĩ sẽ rất dễ dàng để các trình duyệt sử dụng các phiên độc lập trên các tab. Tệ hơn nữa, ngay cả khi bạn quản lý một trình duyệt để làm điều đó, vẫn còn những người khác 'sửa'. – keyboardP

Trả lời

4

Hãy nghĩ đến việc sử dụng ViewState thay vì Phiên, vì ViewState hiển thị thông tin trạng thái cho khách hàng (trang HTML). Tôi không chắc liệu bạn có bao giờ có thể kiểm soát chi tiết hành vi phiên của trình duyệt hay không, bởi vì ID phiên được duy trì bởi trình duyệt theo cách nhà sản xuất đã thực hiện nó. Vì vậy, ViewState là dễ đoán hơn, không chỉ mà còn cho các phiên bản trình duyệt trong tương lai.

+1

Chỉ cần làm rõ, bằng cách 'an toàn', tôi đoán bạn không có ý nghĩa từ quan điểm tấn công của hacker. – keyboardP

+0

Không, không hề, bạn nói đúng. Tôi đã chỉnh sửa bài đăng. –

2

Người dùng có được đăng nhập bằng các tài khoản khác nhau để truy cập các kiểm tra thực tế khác nhau không? Dường như với tôi rằng miễn là PhysicalInspectionID là một phần của URL, thì sẽ không có vấn đề gì khi chỉnh sửa nhiều lần kiểm tra vật lý cùng một lúc.

Ví dụ:

http://inspections.mydomain.com/edit/23

Tất nhiên, nếu họ sao chép URL, họ sẽ nhận được một bản sao của một cửa sổ khác, nhưng điều này sẽ dạy cho họ không làm điều đó. Thay vào đó, họ mở một cửa sổ khác và duyệt đến kiểm tra thích hợp (hoặc thêm một cửa sổ mới) thông qua giao diện người dùng.

0

Tạo phiên mớiId khi yêu cầu không có tham chiếu. Điều đó giải quyết vấn đề url sao chép-dán. Lưu sessionId trong url như bạn đã làm.

3

đây là một câu hỏi rất hay mà tôi cũng đã suy nghĩ lâu dài và vất vả.

Lưu trang web chính của bạn vào khung nội tuyến. Có javascript để kiểm tra xem trang web của bạn có nằm trong khung nội tuyến chính hay không. Nếu không, thì họ đã mở nhiều cửa sổ trình duyệt.

Bạn cần đảm bảo toàn bộ ứng dụng của mình là khung nội tuyến thân thiện.

+3

bạn thực sự đã nói điều đó. Lúc đầu, tôi nghĩ rằng bạn đã nói đùa, nhưng tôi không nghĩ rằng bạn đang có. IFRAME? – jDeveloper

3

Tôi không chắc chắn lý do tại sao bạn muốn hạn chế phiên chỉ xử lý một quy trình kiểm tra và sau đó buộc nhiều phiên để người dùng làm việc đồng thời trên nhiều lần kiểm tra. Điều đó cảm thấy giống như một phong cách khá ngượng ngùng của sự cô lập.

Ứng dụng web (và các trang) phải có khả năng xử lý nhiều quy trình kiểm tra trong một phiên người dùng duy nhất.

Bất kỳ dữ liệu nào đang được giữ trong các biến phiên sẽ không được hiển thị rõ ràng để xử lý số ít.Chúng phải được lưu trữ trong bộ sưu tập để dễ dàng xác định tập hợp dữ liệu nào thuộc về quy trình kiểm tra nào. Mỗi lần gửi trang trở lại máy chủ web phải mang theo một định danh mà quá trình kiểm tra nó liên quan đến, để tập hợp phiên đúng có thể được khớp và kéo để sử dụng.

mã giả khái niệm

var inspectionID = this.inspectionLabel.Text; 
var inspectionSets = (Hashtable)Session["inspections"]; 
var inspection = (Inspection)inspectionSets[inspectionID]; 
1

Đây là những gì tôi sử dụng trong ASP.NET MVC cấm người dùng xác thực để mở nhiều tab:

<script language="javascript" type="text/javascript"> 
    @if(Request.IsAuthenticated) 
    { 
     <text> 
     if (window.name != 'singleWindow') { 
      window.location.href = "Content/ErrorPages/SingleTab.htm"; 
     } 
     </text> 
    } 
    else 
    { 
     <text> 
     window.name = "singleWindow"; 
     </text> 
    } 
</script> 

Về cơ bản, điều này đặt tên cửa sổ lần đầu tiên khi người dùng truy cập trang đăng nhập. Sau khi đăng nhập, mỗi trang tiếp theo tải tên cửa sổ sẽ được kiểm tra.

Hai vấn đề:

  • không Wok nếu Javascript tàn tật
  • nếu do nhầm lẫn người dùng đóng tab gốc và sau đó dán một số liên kết khác để trang web của tôi vào thanh địa chỉ, người dùng sẽ luôn nhận được trang lỗi. Để cung cấp cho người dùng cơ hội khôi phục, tôi đã bao gồm liên kết "Đăng xuất" trong trang SingleTab.htm, vì vậy người dùng có thể hủy cookie phiên của mình và bắt đầu một phiên mới.
2

Một giải pháp cho vấn đề đó có thể được thực hiện bằng cách sau:

public static class CommonHelper 
{ 
    public static bool SiteGuard 
    { 
     get 
     { 
      if(HttpContext.Current.Session["SiteGuard"] == null) 
       return true; 
      return (bool)HttpContext.Current.Session["SiteGuard"]; 
     } 
     set 
     { 
      HttpContext.Current.Session["SiteGuard"] = value; 
     } 
    } 
} 

public partial class TestPage : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     if(!Page.IsPostBack) 
     { 
      bool go = false; 
      for(int i = 0; i < 50; i++) // wait for the service to work (5 secs max) 
      { 
       if(CommonHelper.SiteGuard) 
       { 
        go = true; 
        break; 
       } 
       Thread.Sleep(100); 
      } 
      if(!go) 
       Response.Redirect("Login.aspx"); 

      SiteGuard = false; // from now on, nobody can visit your site 
     } 
     // Now as long as Page.IsPostBack is true you are in a good shape 
    } 
} 

Thêm một dịch vụ asmx web (hoặc bất kỳ loại khác của các dịch vụ mà bạn nghĩ là phù hợp) cho dự án gốc của bạn và thêm dòng sau phương pháp với nó:

[WebMethod(EnableSession = true)] 
    public void FreeSiteGuard() 
    { 
     HttpContext.Current.Session["SiteGuard"] = null; 
    } 

Trong trang chủ, hoặc trên mỗi trang thêm javascript sau:

<script type="text/javascript"> 
    window.onbeforeunload = function (e) { 
     e = e || window.event; 
     if (e) { 
      // Invoke web service 
      YourProject.YourWebServiceName.FreeSiteGuard(); 
     } 
    }; 
</script> 

Lưu ý rằng thời gian phản hồi trang web của bạn bị ảnh hưởng bởi tốc độ của dịch vụ web.

+0

Điều gì sẽ xảy ra nếu người dùng bật JavaScript? – kat1330

+0

Bạn có thể phát hiện điều đó và ngăn người dùng thực hiện bất kỳ điều gì ngay từ lần bắt đầu đầu tiên. Nhắc anh ta bật JavaScript. – yazanpro

+0

Bạn có thể thay thế cuộc gọi webservice bằng một cuộc gọi Ajax đến một trang trong ứng dụng web. – ZooZ

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