Tại sao giỏ hàng lại lưu lại ở trong Session?

Ôi liên quan tới bảo mật đúng là khổ quá mà :((
Em cảm ơn bác nhiều ạ

Đúng là có thể hijack cookie (hacker có thể hứng đoạn dữ liệu đang chạy lên server, để sửa đổi hoặc lấy trộm) hoặc nếu máy tính của user bị cài virus có thể chôm cookie từ browsers.
Cách này có thể xử lý bằng cách

  • mã hoá cookie bằng keypair hoặc keystore, chỉ được mã hoá khi gửi lên server với private key hoặc chỉ key (tương ứng cho keypair và keystore)
  • Cài đặt tcl/ssl để mã hoá các dữ liệu thô khi gửi lên bằng post/delete/update v.v

Lúc login có thể gửi về một JWT(Json web token) về cho client, kèm cái username để display cho vui. Lưu những dữ liệu này xuống client, username để display lên giao diện. Khi có những request lên server thì gửi kèm cái JWT này lên. Server sẽ kiểm tra JWT này có valid hay không để process hoặc trả về 403. Đối với các action nào của user mà update dữ liệu thì có thể xin hỏi nhập lại password (giống facebook)
Cách mã hoá token có thể sử dụng như cái bước mã hoá cookie đã ghi ở trên.

Tuy nhiên điều kiện tiên quyết là không được lưu trữ password hoặc id định danh ở dưới client. Việc bảo mật rất quan trọng và cũng rất phức tạp.

JWT bản thân nó đã chứa vài thông tin cơ bản khi mình định nghĩa ví dụ như ID, username rồi bạn.

2 Likes

Amen , thà không hỏi thì yên tâm mà làm , đọc xong em thấy em phải học nhiều thứ quá :((
Nếu được bác cho em xin 1 đoạn code demo được không ạ ?
Em xin chân thành cảm ơn

Đúng rồi bạn, payload thì mình để gì cũng được. Nhưng JWT có 2 chức năng lận. Và mình dùng JWT như là single-sign on.

Sau khi review kỹ thì thấy em ko cần phải xài token as single sign on chi nhé, vì nói tới nó thì liên quan tới cross-flatform . Chỉ đơn giản set cookie khi đăng nhập thành công. Muốn set thêm các display_name thì gắn thêm cookie vào.

int timeout = rememberMe ? 525600 : 30; // Timeout in minutes, 525600 = 365 days.
var ticket = new FormsAuthenticationTicket(userName, rememberMe, timeout);
string encrypted = FormsAuthentication.Encrypt(ticket);
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encrypted);
cookie.Expires = System.DateTime.Now.AddMinutes(timeout);// Not my line
cookie.HttpOnly = true; // cookie not available in javascript.
Response.Cookies.Add(cookie);

JWT và SSO là 2 vấn đề khác nhau.
Nếu bạn dùng token do server trả về như 1 string không bao gồm bất kì thông tin gì thì hãy gọi đó là 1 token thông thường. JWT sinh ra không dành cho mục đích đó.
Việc bạn dùng Token thông thường chẳng liên quan gì tới SSO cả, đừng lạm dụng khái niệm.

3 Likes

Well, phiên bản đơn giản nhất của SSO là trên cookie, tuy nhiên nó bị giới hạn bởi domain. Cho nên mới sản sinh ra token để có thể nói chuyện trên nhiều domain hoặc cross-flatform.

Nếu token thông thường ko liên quan thì cái gì liên quan đây???
Và Token thường được tạo theo nhiều cách tuỳ người build kiến trúc, và JWT(Introduction) thì là một trong số đó.

1 Like

Nếu bạn cứ nhấn mạnh vào SSO vậy thì tự bạn build authenticate server và dùng cho 1 website như trong trường hợp của chủ thớt à?
Nếu chính web site đó issue token thì hãy gọi đó là quá trình authenticate như bình thường, không có dấu hiệu của SSO ở đây.

2 Likes

Set cookie cùng một parent domain (eg: .abc.com) thì các sub-domain cũng có thể sử dụng chung.
Đã hướng dẫn chủ thớt sử dụng cookie cho simple rồi nhé.
Các vấn đề khác mình không bàn nữa nhé.

Tại sao giỏ hàng lại lưu lại ở trong Session?
Đối với các tutorial thì mình nghĩ lưu trong session dễ hiểu dễ thực hiện cho người mới hơn các cách khác. Tất nhiên là có nhược điểm rồi. Bạn tắt trình duyệt đi sẽ mất luôn. Câu hỏi này mình chỉ trả lời đến đây thôi nhé. Phần bên dưới là những cách khác để lưu lại, tuỳ từng mục đích để chọn.
1. Sử dụng session:

  • Nhanh, dễ tiếp cận.
    Nhược điểm:
  • Tắt trình duyệt giỏ hàng sẽ bị xoá.
  • Về kiến trúc stateless sẽ không được khuyến khích. Client và server sẽ không lưu dữ liệu của nhau trong kiến trúc này nên sẽ không sử dụng session.
  • Đối với 1 trang web lớn có sử dụng nhiều server để cân bằng tải, việc giữ session đồng bộ tất cả server khá mệt.
    2. Client sẽ lưu lại giỏ hàng:
  • Cách này thường sử dụng cookie hoặc localStorage để lưu lại.
  • Nó sẽ không bị mất khi bạn tắt trình duyệt, đồng thời giảm tải cho server (không phải lưu cái gì).
    Nhược:
  • 1 số browser cũ không hỗ trợ localStorage nhưng vẫn có thể dùng cookie thay thế (cookie lưu max được 4kb).
    3. Lưu vào database: Cũng được nhưng chưa thấy ai áp dụng cho sản phẩm cả. Database sẽ phình lên nhanh chóng, gánh nặng lên server luôn. Cái này không khuyến khích.
1 Like

@JOEY: you do not misunderstood. And a lot of “experts” join in to show off skills, we’ve came with a lot of too advantage solutions. But clearly he just need simple one. Cookie is enough.

Thử add to cart tiki bằng chrome và firefox xem ?

thử rồi bạn nhé, có vấn đề gì nhỉ?

2. Client sẽ lưu lại giỏ hàng:
- Cách này thường sử dụng cookie hoặc localStorage để lưu lại.
- Nó sẽ không bị mất khi bạn tắt trình duyệt, đồng thời giảm tải cho server (không phải lưu cái gì).
- Bạn yên tâm sử dụng nhé, ông lớn như tiki cũng đang dùng cách này.
Nhược:
- 1 số browser cũ không hỗ trợ localStorage nhưng vẫn có thể dùng cookie thay thế (cookie lưu max được 4kb).

Mình quote lại đoạn này nhé. Sau khi check tiki thì thấy có request lên server khi đặt hàng. Không rõ là có lưu trong db hay không nhưng nó đã không dùng localStorage như ngày xưa nữa. Thank @Nancru đã check.
Bổ sung: nếu lưu trong db thì nên làm 1 con cron job đi xoá dữ liệu sau 1 khoảng thời gian (amazon lưu 90 ngày mới xoá) để đỡ nặng db. :slight_smile:

2 Likes

Trước đây mình có làm 1 project liên quan đến vấn đề đặt hàng từ các trang TMDT bên TQ.
Ban đầu dùng localStorage khá ok nhưng có nhiều khách hàng phàn nàn rằng họ thường xuyên thay đổi trong giỏ hàng, có khi đắn đo cả tuần mới quyết định đặt.
Trong thời gian đó họ phải làm việc ở nhiều máy tính, máy cơ quan, máy ở nhà…
Nên họ muốn dữ liệu giỏ hàng phải được access từ tất cả các máy khi họ đăng nhập và mình phải lưu giỏ hàng vào DB.

5 Likes

À đương nhiên là đăng nhập sẽ lưu vào db, còn guest thì bạn có thể chọn localStorage, session hoặc cookie mà. :slight_smile:

Đúng là như vậy, tuỳ vào từng điều kiện cụ thể mà mình phải quyết định giải pháp nào là tối ưu.

2 Likes

M nghĩ nếu bạn muốn học chuyên sâu thì ko nên cái gì cũng đi xin code như này . Bạn có thể google rồi tự code có lỗi gì mà tìm ko ra thì up lên đây để mn giúp thì hơn.
Với chủ đề này m khuyến nghị bạn đọc thêm về Session, cookie, localStorage . So sánh giữa chúng giống và khác nhau điểm gì. Từ đó bạn sẽ biết khi nào dùng cái nào để lưu dữ liệu, cái nào để lưu thông tin đăng nhập…

1 Like

Vâng , nhờ bác phân tích em cũng hiểu hơn rồi ạ .

Vâng như các bác phân tích thì em hiểu vấn đề của em rồi ạ .

Vâng em có tìm hiểu sơ lược qua rồi đó chứ ạ , vâng xin code demo là điều không nên , em không biện hộ , còn về đọc thêm thì em có đọc em mới lập top này hỏi , vấn đề nảy sinh khi em đang làm theo hướng dẫn , tắt trình duyệt bật lại thì cái giỏ hàng nó vệu , đi tìm hiểu thì em mới thấy session nó như thế , cookie nó như vậy ,còn khái niệm localStorage thì có bác trên mới chỉ em mới biết để đi tìm hiểu chứ , em mới thắc mắc là tại sao lại dùng session để lưu giỏ hàng trong khi nó có nhược điểm như thế ? phải chăng vì lý do nào đó ( tốt cho sever , nhanh … ) mà em không biết nên em mới đi hỏi đó chứ .

Túm cái váy lại em cảm ơn mọi người rất rất nhiều , qua topic này em đã hiểu ra được rất rất nhiều điều .
Một lần nữa em xin chân thành cảm ơn ạ.

Các trang thương mại điện tử thường sẽ lưu lại session của người dùng. Tại sao? để phân tích dữ liệu. Ví dụ người ta mới chỉ lựa để trong cart mà k mua. server sẽ lưu lại những thông tin này để phục vụ cho bên sử dụng dữ liệu. session để chỉ phiên làm việc. Bạn có thể lưu trong database. trong in-memory db (redis/memcached…). Đối với guest thì có thể như thế này:

  • Khi khách vào trang lần đầu. -> check cookies trong request xem có sessionId chưa.
    -> Chưa có? Sign cho 1 session cái lưu lại trong db/redis rồi gửi cho nó cái sessionId.
    -> có rồi? Ok vậy là mỗi request tới từ người dùng ta sẽ biết phiên làm việc này là của ai. Và các thông tin về giỏ hàng hoặc hành vi người dùng có thể lưu lại theo session phía dưới backend. Đây cũng là 1 cách implement bảo mật thông tin hơn thay vì lưu trên client side. Nếu bạn lo lắng về việc cookie có thể bị chôm bởi package gửi đi thì dùng https. Mã hóa dữ liệu trước khi gửi đi. Lo về việc bị chôm bằng javascript thì có thể set cookie với flag http-only = true… Còn hắc cơ mà cầm vào đc tận máy người dùng rồi thì lưu ở đâu cũng vậy thôi. :smile:

Bạn thắc mắc là làm sao điều khiển được thời gian sống của session? Ví dụ cho vào giỏ 10 ngày sau mở web lên vẫn còn thì bạn có thể set thời gian sống của cookie chứa sessionId của phiên đó. hết thời gian sống -> hết access -> sau đó xóa dưới server đi hay giữ lại là tùy bạn.

Mà cái này thì chẳng liên quan đến cái signle sign on như bạn nào đó nói. Đừng confuse. Đơn giản chỉ là lưu cart thì sso làm gì? Nghĩ đơn giản thôi. Tìm hiểu kỹ về cookies, session, và 1 số các pattern phổ biến bạn sẽ tự biết làm thế nào để phù hợp với scope của bạn

5 Likes

Vâng em cảm ơn bác rất rất nhiều , em sẽ học tập cách làm này và thử áp dụng .
Một lần nữa em cảm ơn bác rất nhiều ạ.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?