Đây là phần 1 trong chuỗi các bài viết về authentication. Trong series này, chúng ta sẽ làm rõ các phương pháp authentication phổ biến như Basic Authentication, JWT, Oauth 2.0,…
Series này sẽ giúp các bạn hiểu rõ hơn về các phương pháp authentication, và cách sử dụng chúng trong các ứng dụng web.
Luồng hoạt động của authentication
Để hiểu rõ hơn về authentication, chúng ta cần phải hiểu flow hoạt động của authentication.
Dù cho ngày nay có nhiều phương pháp authentication, nhưng flow của chúng cơ bản vẫn giống nhau.
Ví dụ bạn muốn truy cập vào một trang web mà cần phải đăng nhập.
Bước 1
Client sẽ gửi một request lên server chứa thông tin định danh client là ai, cái này có thể là username/password, một đoạn mã nào đấy, hoặc là token, hoặc là một số thông tin khác.
Bước 2
Server sẽ kiểm tra thông tin định danh của client với thông tin trong database. Nếu thông tin định danh đúng, server sẽ trả về một dấu hiệu gì đó để cho client biết là đăng nhập thành công.
Bước 3
Client sẽ lưu lại dấu hiệu này, và gửi dấu hiệu này lên server mỗi khi client muốn truy cập vào các tài nguyên của server.
Bước 4
Server sẽ kiểm tra dấu hiệu, nếu hợp lệ, server sẽ trả về tài nguyên cần thiết.
Bây giờ thì đi đến kỹ thuật authentication cổ xưa nhất là Basic Authentication.
Basic Authentication
Basic Authentication được coi là phương pháp authentication đơn giản nhất cho một website.
Flow làm việc của nó rất dễ:
-
Khi bạn truy cập website sử dụng cơ chế Basic Authentication, server sẽ kiểm tra Authorization trong HTTP header. Nếu Authorization không hợp lệ, server sẽ trả về một response với WWW-Authenticate nằm trong header. Cái này nó sẽ làm website bạn hiển thị popup yêu cầu bạn nhập username/password.
-
Bạn nhập username/password, bạn nhấn OK thì trình duyệt sẽ tiến hành mã hóa (encode) username/password thành một chuỗi base64 theo quy tắc username:password, và gửi lên server thông qua HTTP header Authorization.
-
Server sẽ kiểm tra và giải mã Authorization trong HTTP header. Nếu hợp lệ, server sẽ trả về thông tin website, nếu không hợp lệ, server sẽ trả về một popup yêu cầu bạn nhập lại username/password.

Sơ đồ cơ chế Basic Authentication
Chúng ta cùng tìm hiểu thông qua đoạn code bên dưới
Đây là đoạn code NodeJs để tạo một server sử dụng Basic Authentication:
const express = require('express')
const app = express()
const port = 3000
// Hàm xác thực Basic Authentication
function authenticate(req, res, next) {
const authHeader = req.headers.authorization
console.log(authHeader) // Basic dXNlcm5hbWU6cGFzc3dvcmQ=
if (authHeader) {
// Giải mã chuỗi base64
const auth = Buffer.from(authHeader.split(' ')[1], 'base64').toString().split(':')
const username = auth[0]
const password = auth[1]
if (username === 'username' && password === 'password') {
return next()
}
}
// WWW-Authenticate sẽ giúp trình duyệt hiển thị popup đăng nhập
// Ở đây, Basic chỉ ra rằng máy chủ yêu cầu xác thực Basic Authentication.
// realm (optional) là một thuộc tính tùy chọn mô tả phạm vi bảo mật của tài nguyên được yêu cầu.
// Giá trị cái realm này chỉ để mô tả thôi, không có cũng được
res.setHeader('WWW-Authenticate', 'Basic realm="example"')
res.status(401).send('Authentication required')
}
// Sử dụng hàm xác thực cho tất cả các route
app.use(authenticate)
// Route chào mừng
app.get('/', (req, res) => {
res.send('Chào mừng bạn đến với ứng dụng Node.js sử dụng Basic Authentication!')
})
// Khởi chạy máy chủ
app.listen(port, () => {
console.log(`Máy chủ đang chạy tại http://localhost:${port}`)
})

P opup này là do trình duyệt hiển thị
Vậy làm thế nào để tôi logout khỏi website?
Câu trả lời là khi bạn tắt hoàn toàn trình duyệt, lúc đó bạn mới logout ra.
Ứng dụng của Basic Authentication
Mặc dù đây là phương pháp đơn giản, thô sơ, nhưng nó vẫn được sử dụng rất nhiều trong các ứng dụng web.
Ví dụ 1
Dự án website của bạn khi release thì có 2 môi trường là staging và production. Vì là môi trường staging, vẫn còn đang trong giai đoạn phát triển, nên bạn muốn chỉ cho những người trong nhóm phát triển truy cập vào website. Vậy thì bạn có thể sử dụng Basic Authentication để yêu cầu người dùng phải nhập username/password để truy cập vào website. Đỡ phải code thêm một chức năng đăng nhập phức tạp.
Ví dụ 2
Trong quá trình phát triển backend thông thường team backend sẽ gửi document cho các team kết nối vào api, ví dụ sử dụng swagger
. Và tất nhiên bạn không muốn những người không liên quan truy cập vào, và Basic Authentication là giải pháp nhanh để tích hợp một lớp bảo mật cho document.
Đánh giá ưu nhược điểm của Basic Authentication
Ưu điểm
Đơn giản, dễ hiểu, dễ triển khai. Làm được trên Nginx hay Apache luôn cũng được, không cần can thiệp vào code backend.
Nhược điểm
-
Không an toàn, vì username/password được mã hóa bằng Base64. Kẻ gian có thể đánh cắp đoạn mã base64 này thông qua việc bắt request (Tấn công Man-in-the-middle). Vậy nên cần phải sử dụng HTTPS để mã hóa giao tiếp giữa client và server.
-
Thiếu tính linh hoạt: Basic Authentication không hỗ trợ nhiều cấp độ xác thực, quản lý quyền truy cập, hay gia hạn/ thu hồi quyền truy cập. Điều này giới hạn khả năng mở rộng và kiểm soát truy cập trong các ứng dụng phức tạp.
-
Không thể logout khỏi website. Vì Basic Authentication chỉ yêu cầu người dùng nhập username/password khi truy cập vào website, nên khi bạn tắt trình duyệt, bạn mới logout ra.
-
Không thể sử dụng được cho các ứng dụng mobile. Vì Basic Authentication yêu cầu người dùng nhập username/password, nhưng trên các ứng dụng mobile thì không có giao diện để người dùng nhập username/password.
Đón chờ phần kế tiếp chúng ta sẽ tìm hiểu tiếp về các phương thức xác thực khác…