Có nên tránh các biến phiên?


36

Tôi đã từng phụ thuộc rất nhiều vào các biến phiên trong quá khứ, nhưng gần đây đã tìm thấy nhiều trong số chúng là không cần thiết, sử dụng những thứ như tham số chuỗi truy vấn thay thế.

Một đồng nghiệp của tôi từ chối sử dụng các biến phiên. Đây có phải là một mục tiêu thực tế và nên tránh các biến phiên vì bất kỳ lý do thực tế nào không? Các biến phiên có thể tránh hoàn toàn (ngoại trừ cookie phiên để cho phép đăng nhập) và điều này có dẫn đến thiết kế tốt hơn không?

Một số lý do đồng nghiệp của tôi đã không sử dụng chúng:

  • Bản chất của các biến phiên
  • Thời gian chờ phiên gây mất trạng thái
  • Bản chất phạm vi toàn cầu của các biến phiên
  • Tải các máy chủ cân bằng mất phiên (cụ thể .Net?)
  • Nhóm ứng dụng / máy chủ khởi động lại
  • Chúng không cần thiết

3
using things like query string parameters instead- Với trường hợp này, luôn luôn sử dụng các tham số chuỗi truy vấn nếu có thể. Sử dụng phiên cho loại tham số đó rất mong manh và có thể gây ra các lỗi lạ khi người dùng mở nhiều tab.
Izkata

2
đề nghị cá nhân - không nhận bất kỳ lời khuyên nào từ đồng nghiệp của bạn vì anh ấy rõ ràng không biết anh ấy đang nói về điều gì. Thời gian chờ phiên? Anh ta không nhận ra thời lượng phiên được kiểm soát bởi ứng dụng web?
GrandmasterB

2
@GrandmasterB Ahem. Không biết họ đang làm gì hoặc đã bị đốt cháy bởi mỗi một trong những gạch đầu dòng đó trong suốt sự nghiệp của họ (bản thân tôi đã đánh khoảng 4 người trong số họ) và biết nhiều cách thích hợp hơn để đối phó với trạng thái tạm thời.
Ed James

Ai đó có thể vui lòng giải thích mối quan hệ giữa trạng thái phiên và mở nhiều tab không? Khi bạn mở một tab mới, hiện tại nó có chứa trạng thái từ tab trước không? Cảm ơn.
Ray

Câu trả lời:


41

Nếu bạn có một biến phiên trong ứng dụng của mình, hãy tự hỏi điều này:

Khi tôi nhấp vào nút quay lại của trình duyệt, tôi muốn biến của mình có giá trị gì?

Nếu câu trả lời là "giá trị hiện tại", các biến phiên có thể hữu ích. Một ví dụ sẽ là giỏ hàng: bạn không hy vọng mọi thứ sẽ bị xóa khỏi giỏ hàng khi bạn quay lại lịch sử. Nó luôn ở trạng thái hiện tại.

Nếu câu trả lời là "giá trị trước", bạn không nên sử dụng biến phiên. Sử dụng xấu tôi đã thấy bao gồm việc chuyển một tham số giữa các trang. Nếu tôi nhấp vào nút quay lại để quay lại trang, trang đó không nhất thiết phải có thông số chính xác. Ngoài ra, nếu tôi mở hai tab, trang web của tôi sẽ hoạt động như thế nào?

Không có nghĩa là hành vi của nút quay lại không phải là tất cả và cuối cùng, nhưng nó giúp bạn nghĩ về một trang web như một ứng dụng phi trạng thái. Nói chung, tôi thấy việc sử dụng các biến phiên thích hợp là rất ít và xa.


Tôi đồng ý. Khi bạn nghĩ về ngữ nghĩa mong muốn với nhiều tab, điều này thường trở nên rõ ràng nếu các biến phiên hoặc tham số yêu cầu là lựa chọn đúng.
CodeInChaos

Tôi đã thấy chính xác các loại lỗi này với các biến phiên và phải thừa nhận bản thân đã học một cách khó khăn.
Tjaart

Khi người dùng nhấn nút quay lại, họ có mong đợi các mặt hàng sẽ ở trong giỏ hàng cho đến khi phiên của họ hết hạn hay họ muốn các mặt hàng ở lại cho đến khi chúng được lấy ra? Sử dụng một số cơ chế lưu giữ lâu dài khác (như cơ sở dữ liệu) sẽ cho phép tồn tại lâu hơn một phiên và nút quay lại của bạn sẽ vẫn hoạt động như người dùng mong đợi.
Lawtonfogle

25

Giao thức HTTP không trạng thái. Phiên là một cách để duy trì trạng thái máy khách trên các yêu cầu HTTP. Bạn có thể chọn thực hiện điều đó với xử lý phiên dựng sẵn của nền tảng hoặc tự thực hiện với các tham số chuỗi truy vấn. Dù bằng cách nào đó, một số khái niệm về một phiên là cần thiết cho nhiều nhiệm vụ.

Đồng nghiệp của bạn có thể không thích triển khai cụ thể hoặc đã không sử dụng các phiên cho mục đích dự định của họ. Nếu bạn cần giữ lại thông tin về một kết nối máy khách cụ thể qua các yêu cầu HTTP, bạn cần một số hình thức duy trì phiên.

Các vấn đề sau đây là cụ thể thực hiện:

Bản chất của các biến phiên

Bản chất phạm vi toàn cầu của các biến phiên

Tải máy chủ cân bằng mất phiên

Nhóm ứng dụng / máy chủ khởi động lại

Ví dụ, tôi thường xuyên làm việc trong PHP và lưu trữ thông tin phiên của tôi trong cơ sở dữ liệu quan hệ. Vì vậy, các biến phiên của tôi được gõ. Cân bằng tải và khởi động lại máy chủ không gây ra bất kỳ vấn đề nào về phiên.

Điều này thú vị hơn:

Thời gian chờ phiên gây mất trạng thái

Các phiên thường được bảo quản thông qua cookie. Chúng có thể bị xóa bởi khách hàng bất cứ lúc nào. Nhưng chúng cũng có thể được bảo tồn thông qua một tham số chuỗi truy vấn và do đó không bao giờ hết thời gian trên máy khách. Thời gian chờ máy chủ là tùy thuộc vào bạn. Vì vậy, ngay cả vấn đề này là thực hiện cụ thể.

Chúng ta đừng bỏ qua toàn bộ khái niệm về các phiên chỉ vì chúng ta không thích một triển khai cụ thể. Bất kỳ khung ứng dụng web tốt nào cũng sẽ tạo điều kiện sử dụng phiên đúng cách để duy trì thông tin đăng nhập của người dùng hoặc giữ lại mọi thứ khác cụ thể cho lượt truy cập hiện tại của người dùng. Bản ghi cơ sở dữ liệu của người dùng có thể (và nên) được sử dụng để lưu trữ những thứ cụ thể cho họ khi đăng nhập. Tuy nhiên, khách truy cập ẩn danh có thể có thông tin tạm thời cũng đáng được lưu giữ trong phiên của họ, chẳng hạn như một danh sách ngắn các trang gần đây đã truy cập hoặc tùy chọn ẩn một thông báo mà họ đã thấy. Nói chung chỉ thông tin tạm thời nhỏ hơn là thích hợp để lưu trữ phiên.


Thành thật mà nói, tôi đã có kinh nghiệm hạn chế với các khung bên cạnh .Net. .Net dừng việc ép buộc giá trị hết thời gian cho các phiên của bạn. Các biến phiên cũng tạo ra mã phía máy chủ dưới dạng từ điển chưa được gõ. Tôi thường bọc từ điển này trong các lớp được gõ đúng cách, vì vậy tôi cũng không xem đây là một vấn đề. Bạn đã đề cập rằng bạn lưu trữ thông tin phiên của bạn trong cơ sở dữ liệu. Trong ASP .Net, bộ lưu trữ được xử lý theo cách khác, trong máy khách .Net, trong cơ sở dữ liệu (được quản lý tự động) hoặc trong một dịch vụ windows riêng.
Tjaart

Bạn có thể đưa ra một số ví dụ về mục đích dự định cho các phiên?
Tjaart

@Tjaart: Tôi đã mở rộng đoạn cuối một chút. Mong rằng sẽ giúp.
Matt S

14

Những người khác đã đưa ra rất nhiều điểm tốt (mà tôi sẽ tránh lặp lại), nhưng có một khía cạnh trong kỹ thuật của bạn của bạn chưa được thảo luận: bảo mật .

Không thể biết loại lỗ hổng nào bạn mở ra mà không nhìn vào mã, nhưng đây là một vài điều tôi có thể nghĩ ra khỏi đỉnh đầu.

  • Sửa lỗi phiên : Một cuộc tấn công mạnh mẽ dễ dàng hơn một chút nếu bạn chỉ cần người dùng nhấp vào một liên kết đã có thông tin cần thiết trong URL (thay vì cố gắng để người dùng sử dụng máy có cookie được đặt phù hợp).
  • SQL SQL (hoặc đầu vào độc hại khác) : Không bao giờ tin tưởng bất cứ điều gì đến từ người dùng. Biến phiên có một lợi thế là không bao giờ rời khỏi máy chủ, do đó người dùng không thể trực tiếp thay đổi chúng. Mặc dù bạn nên vệ sinh dữ liệu trước khi đưa nó vào phiên, bạn luôn có thể tin tưởng vào các giá trị bạn nhận được sau đó. Nếu mọi thứ được chuyển qua chuỗi truy vấn, bạn có RẤT NHIỀU xác thực bạn cần làm để đảm bảo rằng bạn không chấp nhận đầu vào độc hại.
  • Tham nhũng dữ liệu bằng cách sử dụng các đầu vào sai lệch : Tương tự như SQL tiêm, bạn truyền qua lại bao nhiêu dữ liệu? Nó quan trọng như thế nào? Tôi có thể thay đổi hành vi của ứng dụng của bạn bằng cách thay đổi một giá trị trong chuỗi truy vấn không? Tôi có thể làm hỏng dữ liệu trên máy chủ của bạn bằng cách thay đổi giá trị không? Nếu tôi quản lý để làm hỏng dữ liệu trên máy chủ, nó có ảnh hưởng đến những người dùng khác không? (Nếu câu trả lời của bạn là "không", câu trả lời của tôi là "bạn có chắc không? Bạn có rất nhiều nơi bạn cần kiểm tra.").

Tất cả những điều này vẫn có thể xảy ra khi bạn sử dụng Phiên, nhưng chúng có thể dễ dàng hơn rất nhiều nếu bạn của bạn không biết anh ấy đang làm gì.


2

Các biến phiên giống như các biến toàn cục cơ bản cũ ở một mức độ nào đó. Gánh nặng thuộc về người dùng để theo dõi chúng, những gì trong chúng, phạm vi của chúng và cách chúng được sử dụng; giống như trong các phiên bản cũ của BASIC. Điều đó đang được nói, tại sao một người nào đó hoàn toàn giảm giá việc sử dụng một cơ chế rõ ràng được thiết kế để trở thành một phần không thể thiếu và rất quan trọng của mô hình lập trình (ASP, MVC, v.v.)?

Điều tồi tệ duy nhất mà tôi gặp phải khi sử dụng các biến Phiên là nó đặt gánh nặng lên bạn để theo dõi chúng, đảm bảo chúng được điền với dữ liệu liên quan và xử lý chúng.

Đó không phải là những gì chúng ta làm khi chúng ta lập trình bằng mọi cách sao?


1

Tôi đã từng nghĩ giống như đồng nghiệp của bạn do một số trải nghiệm tồi tệ mà tôi đã gặp phải các vấn đề liên quan đến các biến phiên, điều thực sự không phù hợp với tôi. Có, bạn có thể nhận được ở một mức độ nào đó mà không cần biến phiên, sử dụng chuỗi truy vấn, trường ẩn trong biểu mẫu và những thứ khác. Tuy nhiên, nó sẽ nhanh chóng trở nên cồng kềnh khi thực hiện theo cách này nếu ứng dụng của bạn có bất cứ điều gì ngoài luồng logic cơ bản nhất để xác định trạng thái. Ngoài ra còn có rủi ro bảo mật khi hiển thị hoạt động bên trong của ứng dụng của bạn thông qua các chuỗi truy vấn và các trường ẩn, bất kỳ trường nào có thể đóng vai trò là vectơ tấn công.

Khi làm việc với các biến phiên, bạn chỉ cần theo dõi khi nào chúng được đặt và không được đặt, vì điều này sẽ xác định luồng logic của ứng dụng. Nó giống như quản lý bộ nhớ trong một ngôn ngữ như C.

Lưu ý rằng đây chỉ là kinh nghiệm của tôi khi làm việc với PHP trong một dự án tương đối nhỏ, không có khung, mọi thứ có thể khác trên các nền tảng khác nhưng tôi nghĩ nguyên tắc chung vẫn được áp dụng.


2
Làm thế nào để bạn có được nhiều ngữ nghĩa tab ngay khi sử dụng phiên cho trạng thái liên quan đến luồng kiểm soát của bạn? Các phiên hoạt động tốt để đăng nhập và cài đặt như các thuộc tính, nhưng chúng không có ngữ nghĩa phù hợp cho hầu hết các mục đích sử dụng khác.
CodeInChaos

Tôi không chắc chắn, những gì tôi đã đăng dựa trên kinh nghiệm hạn chế của chính tôi khi xây dựng một ứng dụng web điều khiển cơ sở dữ liệu trong PHP / MySQL. Làm thế nào nhiều tab trong trình duyệt thường được xử lý (Tôi giả sử đó là những gì bạn đang đề cập đến)?
Primehunter326

@ Primehunter326 Với tham số tuyến hoặc chuỗi truy vấn hoặc trường biểu mẫu ẩn.
Casey

0

Như HTTP đã nêu trước đây là Statless và Biến phiên phá vỡ điều đó. Thiết kế HTTP không trạng thái giúp lưu trữ tài nguyên. Đối với các tài nguyên được công khai.

Có thể thiết kế một trang web không có biến phiên nhưng khó hơn. Khó nhất (IMHO) là đăng nhập / đăng xuất ưa thích, các lược đồ xác thực HTTP không cung cấp các công cụ cần thiết để xác thực thông qua biểu mẫu HTML (bạn có thể hack một cái gì đó bằng javascript - XHR sang https: // unlel: passowrd@mydomain.com ) và thậm chí còn khó hơn để đăng xuất và tương thích trình duyệt chéo. đã có một số cuộc thảo luận về danh sách ma thuật w3 về điều đó nhưng nếu tôi nhớ chính xác thì ý tưởng đã bị loại bỏ.

Đối với phần còn lại, bạn sẽ có thể sống mà không cần các biến Phiên. Bạn sẽ có một số trạng thái trên cơ sở dữ liệu, tệp hoặc bất cứ nơi nào nhưng việc sử dụng các biến Phiên sẽ rất hiếm.

Nếu người dùng của bạn có giỏ hàng, đó chỉ là phiên thay đổi nếu người dùng được cho là có thể duyệt trên hai máy tính / trình duyệt mà không chia sẻ giỏ hàng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.