2012-02-09 59 views
5

Tôi đang phát triển một trang web ASP.net (sử dụng .NET 4, EF, jQuery Ajax, SQL Server 2008 R2). Trong trang web này, tôi muốn ngăn chặn multi-login. Tôi có nghĩa là nếu bạn đăng nhập vào trang web, bạn không thể đăng nhập lại vào trang web từ trình duyệt hoặc máy tính khác vì bạn đã đăng nhập rồi.Làm cách nào để ngăn người dùng đăng nhập vào trang web của tôi nhiều hơn một phiên?

Tôi trồng một ý tưởng và phát triển nó trên trang web của tôi, nhưng nó có một vấn đề và đó là vì rằng vấn đề mà tôi quyết định đặt một câu hỏi ở đây

Tôi có một bảng SQL Server như thế này:

Id  [int]   NOT NULL IDENTITY(1,1) //PK 
UserId [int]   NOT NULL     //Relation to User table 
Key  [nvarchar](50) NOT NULL     //Unique 

Khi người dùng đăng nhập vào trang web này, tôi chèn một hàng vào bảng này như thế này:

UserId = The Id of logged in user 
Key = Session.SessionId 

và cũng có một mã cho xóa một bản ghi từ bảng này mà thực hiện wh en:

  1. tài cố gắng để thoát ra khỏi tài khoản của mình
  2. trên Session_End sự kiện trong global.asax

Mọi thứ hoạt động chính xác và hoàn hảo, chỉ cần:

Vấn đề: khi người dùng đóng trình duyệt , hàng đó không bị xóa (tôi nghĩ khi anh ta đóng trình duyệt, hàng của nó trong bảng đó sẽ xóa trên sự kiện Session_End, nhưng nó không !!!)

Tôi có thể làm gì? Bất kỳ giải pháp cho vấn đề này? Tôi có nên thay đổi chiến lược của mình hoặc có giải pháp không?

Xin lỗi về cú pháp không hợp lệ của tôi. Tôi mới bằng tiếng Anh

Bất kỳ ý tưởng có thể hữu ích

liên quan

Foroughi

UPDATE1: tôi không sử dụng ASP thành viên và quản lý người dùng của tôi bản thân mình

UPDATE2: tôi sử dụng InProc mo cho trạng thái phiên của tôi với thời gian chờ 20 phút

+6

Không dễ dàng hơn khi đăng xuất phiên hiện tại khi người dùng đăng nhập mới không? Điều này cũng thực tế hơn khi người dùng quên đăng xuất ở một vị trí khác (ví dụ: nhà riêng/cơ quan). –

+0

@marc_s cảm ơn anh chàng và xin lỗi về họ –

+0

@AliForoughi: không vấn đề gì - câu hỏi vẫn rõ ràng và hoàn toàn dễ hiểu –

Trả lời

2

Sự kiện Session_End không kích hoạt khi trình duyệt đóng, nó sẽ kích hoạt khi máy chủ không nhận được yêu cầu từ người dùng trong một thời gian cụ thể (theo mặc định 20 phút). Điều đó có nghĩa là nếu bạn sử dụng Session_End để xóa người dùng, họ sẽ không thể đăng nhập trong 20 phút sau khi họ đã đóng trình duyệt.

Hai chiến lược thay thế đến với tâm trí

  1. Bạn có thể sử dụng các sự kiện onunload trong trình duyệt để gửi yêu cầu logout đến máy chủ khi người dùng rời khỏi trang (Điều này tất nhiên chỉ hoạt động nếu người dùng vẫn có kết nối mạng). Sự kiện onunload cũng được kích hoạt khi bạn tải lại trang, vì vậy bạn sẽ phải theo dõi lý do sự kiện được kích hoạt để sử dụng nó.

  2. Bạn giữ thời gian của yêu cầu cuối cùng trong đối tượng người dùng. Bằng cách đó bạn có thể xác định người dùng đang hoạt động như thế nào và khả năng họ đã rời khỏi trang web như thế nào. Ví dụ: tìm bất kỳ người dùng nào chưa thực hiện bất kỳ điều gì trong hai phút và đăng xuất chúng.

EDIT: Là điểm cuối cùng được nêu trong nhận xét. Thay vì xem yêu cầu của bạn là ', bạn chỉ có thể có một thông tin đăng nhập, vì vậy nếu bạn đã đăng nhập thì không cho phép đăng nhập' bạn có thể thay đổi thành 'bạn chỉ có thể có một thông tin đăng nhập nếu bạn có phiên mở nó sẽ bị hủy và một cái mới được tạo ra. '

Bằng cách này bạn vẫn giữ nguyên phiên đăng nhập một lần cho mỗi quy tắc tài khoản đồng thời cung cấp phương pháp thực thi mạnh mẽ hơn nhiều.

+0

Tôi cập nhật Câu hỏi của tôi, bạn nghĩ gì bây giờ? –

+0

Tôi nghĩ rằng cái đầu tiên không đủ tốt, nhưng cái thứ hai là tốt và tôi sẽ làm việc trên nó, cảm ơn người đàn ông :) –

+1

Các phương pháp có thể được kết hợp để tận dụng tối đa cả hai thế giới. –

1

Vấn đề bạn có, ngoài cách/nơi bạn lưu trữ trạng thái, là người dùng không thể đăng xuất, do đó để lại một phiên còn sống. Tôi đề xuất như sau:

1) Thay đổi trạng thái (xóa bản ghi trong trường hợp của bạn) khi người dùng đăng xuất hoặc khi phiên kết thúc (phiên kết thúc sau n phút không hoạt động, xem web.config và global.asax của bạn trình xử lý sự kiện)

2) Nếu người dùng cố gắng đăng nhập lần thứ hai, hãy cung cấp tùy chọn đăng xuất phiên trước đó.

+0

Tôi cập nhật Câu hỏi của tôi, bạn nghĩ gì bây giờ? –

0

Tôi nghĩ bạn nên thử dùng thử. như thế này:

cấu trúc bảng:

ID 
UserID 
Flag 

Khi người dùng đăng nhập bạn cập nhật bảng của bạn và thiết lập cờ để đúng hoặc và khi ông được thoát khỏi thiết lập nó để sai hoặc

Khi người dùng đóng trình duyệt của mình, bạn nên quyết định xem bạn có đăng xuất hay không. nếu có - bạn bắt sự kiện này như Session_End và đăng nhập anh ta ra một mình và cập nhật bảng để sai hoặc

2

Trước hết không sử dụng cơ sở dữ liệu như một hệ thống nhắn tin. Đó là một công thức cho thảm họa.

Những gì bạn cần làm là có từ điển chứa id người dùng đã đăng nhập và thời gian hành động cuối cùng của họ trong bộ nhớ Ứng dụng. Ngoài ra, hãy thêm tập lệnh trên tất cả các trang ping máy chủ sau mỗi 2-5 phút.

Sau khi nhận được ping, cập nhật thời gian hoạt động mới nhất của id người dùng và xóa bất kỳ id người dùng nào có 'hết thời gian'.

+0

thảm họa? WOW, ý tưởng của bạn có vẻ tốt, tôi sẽ làm việc trên nó dude, cảm ơn :) –

+1

Lý do tại sao nó là một ý tưởng tồi để sử dụng cơ sở dữ liệu cho tin nhắn nói chung là nó là rất kém hiệu quả. Trong trường hợp này, bạn có thể sử dụng bộ nhớ ứng dụng nhanh hơn. Ngoài ra, trong các tình huống khác, bạn cần phải triển khai các hệ thống phức tạp trên cơ sở dữ liệu để làm cho hoạt động giao tiếp đúng cách (ví dụ: kiểm tra định kỳ thay vì dựa vào sự kiện, dọn dẹp định kỳ, kiểm tra xem tin nhắn đã được đọc, xếp hàng vv ..). Tất cả các cơ chế này thường được thực hiện trong các khung giao tiếp liên ngành thích hợp. – linkerro

+0

"kiểm tra định kỳ thay vì dựa vào các sự kiện"? !! có tôi đã nhận bạn, nó không phải là ý tưởng tồi, nhờ linkerro. tôi nghĩ rằng bạn có nghĩa là để lưu trữ thông tin phiên trong một trạng thái ứng dụng thay DB, và lưu trữ hoạt động cuối cùng của họ? !! –

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