Xác thực người dùng bằng mã token đang ngày càng phổ biến do mô hình client - server được sử dụng rộng rãi. Nếu như trước kia chúng ta thường dùng session hay cookie để xác định phiên người dùng thì giờ đây có thêm một lựa chọn khác là thông qua mã token, đặc biệt là jwt.
Jwt là một chuỗi đùng để định danh, thường là phiên đăng nhập của người dùng. Jwt hoạt động bằng cách kí xác thực vào nội dung được đính kèm trong chuỗi token.
Ví dụ nội chúng ta cần lưu lại những thông tin cơ bản để xác định một người dùng là:
{
"user_id": 1,
"role": "user",
}
Jwt sẽ mã hoá thông tin đó kèm theo một "chữ kí", chỉ máy chủ mới có thể xác thực được chuỗi jwt hợp lệ. Một jwt hợp lệ cũng đồng nghĩa với thông tin đi kèm là chính xác.
Trong jwt thuộc tính exp
là thời gian hết hạn hết hạn của token, một token đã được kí sẽ đi kèm với thời gian hết hạn. Quá thời gian đó token mới thực sự bị vô hiệu hoá. Jwt được thiết kế để giảm tải việc truy vấn vào cơ sở dữ liệu để tìm kiếm thông tin định danh... Máy chủ chỉ đơn giản xác thực token đó là hợp lệ và lấy ra những thông tin cần thiết.
Vì thế jwt chỉ thực sự bị vô hiệu hoá khi exp
đã hết hạn. Vậy thì làm sao để thu hồi lại jwt token khi người dùng đã đăng xuất. Bởi vì bản chất của việc đăng xuất là thoát khỏi phiên, đồng nghĩa với việc token phải không còn hợp lệ
Rõ ràng điều này không có tác dụng gì đối với bảo mật phía máy chủ, nhưng đây là phương pháp đơn giản nhất. Khi áp dụng cách này hãy cầu nguyện rằng hacker sẽ không lấy được mã token của bạn trước khi bạn đăng xuất. Đùa thế thôi bạn chỉ nên áp dụng cách này trong trường hợp bảo mật không quá khắt khe nhé.
Bạn có thể lưu trữ các mã token không hợp lệ cho đến ngày hết hạn đã kí vào chúng và so sánh chúng với các yêu cầu đến.
Tuy nhiên, điều này dường như đã phá vỡ nguyên tắc không truy vấn vào cơ sở dữ liệu ngay từ đầu, vì bạn sẽ cần phải truy vấn vào cơ sở dữ liệu cho mọi yêu cầu.
Nhưng dữ liệu lưu trữ có thể sẽ thấp hơn, vì bạn chỉ cần lưu trữ các mã thông báo mà người dùng đã đăng xuất.
Phương pháp này cũng mang lại một rủi ro chính ra bạn vẫn không chắc chắn được rằng liệu token đã bị đánh cắp trước khi bạn đăng xuất ra hay chưa. Hoặc giả sử như trước khi gọi yêu cầu đăng xuất client bị lỗi không truy vấn được tuy nhiên thì đã xoá dữ liệu ở client, điều đó khiến cho token chưa thực sự được đưa vào blacklist ở máy chủ.
Nếu đã từng nghe đến refresh token thì đây chính là phương pháp sử dụng refresh token để giảm thời gian hết hạn của token xuống mức thấp nhất có thể.
Giữ thời gian hết hạn của token xuống thấp khiến mã token chỉ tồn tại trong thời gian ngắn, khi đó bắt buộc phải dùng mã refresh token để lấy một mã token mới và cứ xoay vòng như vậy. Giả sử token hoặc refresh token bị rò rỉ chúng ta chỉ cần đưa refresh token đó vào blacklist. Điều này cũng giúp cho việc lưu trữ dữ liệu trong blacklist xuống mức thấp hơn so với lưu lại access token.
Trong bất kì trường hợp nào hãy sẵn sàng đối mặt với mã token của người dùng bị rò rỉ và bạn phải xử lý chúng. Một giải pháp đơn giản nhất là làm mất đi hiệu lực của id định danh được lưu trong payload của token. Ví dụ payload bạn kí cho token bao gồm:
{
"user_id": 1,
"role": "user",
}
Thì hãy thay đổi id của user là 1 trong cơ sở dữ liệu. Hoặc nếu nghiêm trọng hãy đổi mã bí mật (secret) dùng để kí mã để làm cho các mã token đã phát hành bị mất hiệu lực ngay lập tức.
Dù sao thì cách trên chỉ là bất đắc dĩ, điều tôi muốn nói là hãy chuẩn bị những phương án dự phòng để đối mặt với việc mã token bị rò rỉ bất kì lúc nào. jwt được thiết kế để giảm tải cho máy chủ, tuy nhiên hãy cân nhắc giữa hiệu suất và bảo mật.
Access Token là một chuỗi được dùng để xác định phiên của người dùng. Khi access token là chuỗi tạo ra theo tiêu chuẩn jwt chúng ta hoàn toàn có thể định danh người dùng mà không cần truy vấn vào cơ sở dữ liệu. Mỗi jwt đi kèm với thời gian hết hạn, nếu chẳng may bị rò rỉ hoặc xử lý token khi người dùng đăng xuất không đúng cách rất có khả năng dữ liệu của người dùng bị tấn công. Chính vì thế hãy thận trọng trong việc xử lý token khi người dùng đăng xuất, đồng thời có những phương án đối mặt với việc mã token bị rò rỉ bất kì lúc nào.
5 bài học sâu sắc
Mỗi sản phẩm đi kèm với những câu chuyện. Thành công của người khác là nguồn cảm hứng cho nhiều người theo sau. 5 bài học rút ra được đã thay đổi con người tôi mãi mãi. Còn bạn? Hãy bấm vào ngay!
Đăng ký nhận thông báo bài viết mới
Xin chào, tôi tên là Hoài - một anh Dev kể chuyện bằng cách viết ✍️ và làm sản phẩm 🚀. Với nhiều năm kinh nghiệm lập trình, tôi đã đóng góp một phần công sức cho nhiều sản phẩm mang lại giá trị cho người dùng tại nơi đang làm việc, cũng như cho chính bản thân. Sở thích của tôi là đọc, viết, nghiên cứu... Tôi tạo ra trang Blog này với sứ mệnh mang đến những bài viết chất lượng cho độc giả của 2coffee.dev.Hãy theo dõi tôi qua các kênh LinkedIn, Facebook, Instagram, Telegram.
Bình luận (1)