Theo Viện Tiêu chuẩn và Kỹ thuật Quốc gia Mỹ (NIST), hình thức nhận mã xác thực một lần qua tin nhắn SMS (SMS TOP) không đủ an toàn.
Theo NIST, không cần truy cập vào thẻ SIM hay điện thoại của bạn, tin tặc cũng có thể hack để chuyển hướng tin nhắn của bạn sang điện thoại của chúng và chiếm đoạt những thông tin quan trọng. Các thủ thuật này tinh vi đến mức bạn sẽ không biết được tin nhắn mình đã bị đánh cắp.
NIST cũng cảnh báo những số điện thoại đăng ký trên các ứng dụng kiểu Facebook Messenger, Viber có khả năng bị hack và làm lộ mã xác thực trên SMS. Đây là những ứng dụng sử dụng VoIP, công nghệ truyền giọng nói qua Internet.
Trước những rủi ro bảo mật, NIST khuyến cáo người dùng nên chuyển sang những ứng dụng tạo mã xác thực một lần, như Google Authenticator, Microsoft Authenticator,... Tin tặc không thể chuyển hướng mã xác thực tạo trên các ứng dụng này.
Trong trường hợp một số trang web chỉ cho phép bạn xác thực 2 yếu tố bằng tin nhắn SMS, bạn vẫn nên sử dụng chúng. Mặc dù cách thức này không an toàn 100%, nhưng vẫn tốt hơn việc bạn chỉ đăng nhập bằng mật khẩu cơ bản.
Xác thực 2FA dần đã khá quen với mọi người. Nó là phương pháp xác thực người dùng dựa trên hai yếu tố, một là mật khẩu ( điều bạn biết ), hai là một thứ mà người dùng sở hữu ( điều bạn có ) như tin nhắn SMS, dấu vân tay, gửi mã token tới email. Bài viết này sẽ sử dụng yếu tố xác thực thứ hai là TOTP ( Time based One time Password ). Để biết chi tiết về cơ chế TOTP như thế nào thì các bạn có thể tìm hiểu thêm trên google.
Hôm nay mình sẽ cùng các bạn triển khai xác thực hai lớp - 2FA với nodejs sử dụng google authenticator.
Workflow của user enable 2FA ( user dùng được chức năng này phải nhập đúng mật khẩu hoặc một cách xác thực nào đó )
1. Tải app google authenticator
2. Login ứng dụng và enable 2FA
3. Scan QR code hoặc nhập secret key.
4. Nhập mã code gg authenticator sinh ra => enable 2FA
Workflow server
- Khi user enable 2FA, secret key sẽ được sinh ra ngẫu nhiên và gán riêng cho mỗi user. ( secret key lưu vào db ).
- QR or mã thủ công sẽ được generate từ secret key và các thông tin liên quan gửi về user.
- User scan và gửi mã code về, server sẽ check.
Bắt tay vào code thôi.
Mình sẽ không code từ đầu, mà sẽ dùng base có sẵn từ những bài viết trước, nếu các bạn chưa đọc thì có thể vào xem ở đây.
https://www.hoangkhanh.tech/2020/08/authentication-use-passport-and-jwt-in.html (Phần 1)
https://www.hoangkhanh.tech2020/08/authentication-use-passport-and-jwt-in_11.html (Phần 2)
Mình sử dụng thêm các module:
- speakeasy : dùng để tạo mã code ( các bạn có thể dùng một thư viện khác, nhưng quan trọng là phải hỗ trợ thằng Google Authenticator nhé )
- qrcode: để sinh ra mã qr cho user scan.
file routes/auth.js ( mình sẽ định nghĩa 2 api, một api để enable 2FA, một api để verify )
file controllers/auth.js
Khi đã enable 2FA mà login thì sẽ như thế này
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_QhQXNHO7tv5SS7litIUebsGEmPbSgSfcgbmNU_2ImMpTHTQMN5sNEVdFabj4SOUm3VPJa5535pGmnoxua_sA5InmXCFYPR8oXMFrI7B7E_JZ90ch2f6f54rxZ0ck1Q7n0HzFvRijjUw/w640-h390/Screen+Shot+2021-04-21+at+09.53.47.png)
Enable 2FA
Đoạn mã qrcode mình để vào thẻ img nhé. Đoạn secret key có trả về cùng, user co thể viết lại ra giấy, tránh trường hợp bị mất điện thoại thì sẽ không login được nữa, vì thằng gg authenticator ko lưu secret key.
Scan qrcode và nó sẽ sinh mã code 6 số theo thời gian.
Nhập mã đúng trong thời điểm đó thì mới login được, còn không sẽ không login được đâu nhé!Docs về thằng speakeasy trên npm mình đọc đau hết cả đầu, vì vậy khi đọc sau docs trên npm bạn có thể tham khảo bài viết sau để đỡ đau đầu hơn nhé. here. Thằng speakeasy mình cũng có thể dùng nó để làm mã otp được, có thời gian thì các bạn tìm hiểu về nó nhé.