Mật khẩu là mắt xích yếu nhất trong bảo mật tài khoản. Chúng có thể bị lừa đảo, rò rỉ, sử dụng lại hoặc quên. Đó là lý do tại sao chúng tôi đã thêm hỗ trợ cho WebAuthn passkeys - một phương thức xác thực không cần mật khẩu, chống lừa đảo, vừa an toàn hơn vừa tiện lợi hơn.

Passkeys là gì?

Passkeys là thông tin xác thực mật mã được lưu trữ trên thiết bị của bạn (điện thoại, laptop, khóa bảo mật) thay thế mật khẩu để xác thực. Chúng sử dụng tiêu chuẩn WebAuthn (một phần của FIDO2) và cung cấp nhiều ưu điểm:

  • Chống lừa đảo - Passkeys được liên kết với tên miền của trang web, vì vậy không thể sử dụng trên các trang web giả mạo
  • Không có bí mật để rò rỉ - Chỉ có khóa công khai được lưu trữ trên máy chủ
  • Liên kết với thiết bị - Khóa riêng tư không bao giờ rời khỏi thiết bị của bạn
  • Bảo vệ sinh trắc học - Thường được bảo vệ bởi Face ID, Touch ID hoặc Windows Hello
  • Đồng bộ xuyên thiết bị - Các nền tảng hiện đại đồng bộ passkeys qua các thiết bị thông qua tài khoản iCloud, Google hoặc Microsoft

Triển khai của chúng tôi

Chúng tôi đã tích hợp hỗ trợ WebAuthn passkey vào ngăn xếp xác thực django-allauth hiện có, cung cấp cả điểm cuối API web và di động.

Luồng đăng ký

Khi người dùng đăng ký một passkey mới, luồng hoạt động như sau:

  1. Client yêu cầu tùy chọn đăng ký từ máy chủ
  2. Máy chủ tạo thử thách với thông tin người dùng và bên tin cậy
  3. API WebAuthn của trình duyệt nhắc người dùng (sinh trắc học hoặc khóa bảo mật)
  4. Client gửi thông tin xác thực trở lại máy chủ
  5. Máy chủ xác minh và lưu trữ khóa công khai
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# Điểm cuối API để bắt đầu đăng ký
class WebAuthnRegistrationOptionsView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        from allauth.mfa.webauthn.internal import auth as webauthn_auth

        # Tạo tùy chọn tạo thông tin xác thực
        creation_options = webauthn_auth.begin_registration(
            request.user,
            passwordless=False  # Sử dụng như 2FA, không phải passwordless
        )

        return Response({
            "success": True,
            "creation_options": creation_options,
        })

Luồng xác thực

Đối với xác thực hai yếu tố sử dụng passkey:

  1. Người dùng hoàn thành xác thực chính (tên người dùng/mật khẩu hoặc đăng nhập xã hội)
  2. Máy chủ trả về thử thách để xác minh WebAuthn
  3. Trình duyệt nhắc cho passkey (chạm sinh trắc học)
  4. Thông tin xác thực được xác minh so với khóa công khai đã lưu
  5. Người dùng được xác thực đầy đủ
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class WebAuthnVerifyView(APIView):
    def post(self, request):
        credential = request.data.get("credential")

        # Hoàn thành xác thực và xác minh thông tin xác thực
        authenticator = webauthn_auth.complete_authentication(
            request.user,
            credential
        )

        # Ghi nhận sử dụng để giám sát bảo mật
        authenticator.last_used_at = timezone.now()
        authenticator.save()

        return Response({"success": True})

Quản lý Passkey

Người dùng có thể quản lý các passkeys đã đăng ký:

  • Liệt kê tất cả passkeys với ngày đăng ký và lần sử dụng cuối
  • Đổi tên passkeys để nhận dạng dễ dàng hơn (ví dụ: “iPhone”, “MacBook”)
  • Xóa passkeys (với bảo vệ chống xóa authenticator cuối cùng)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class WebAuthnListView(APIView):
    def get(self, request):
        authenticators = Authenticator.objects.filter(
            user=request.user,
            type=Authenticator.Type.WEBAUTHN
        ).order_by("-created_at")

        return Response({
            "passkeys": [
                {
                    "id": auth.pk,
                    "name": auth.wrap().name,
                    "created_at": auth.created_at.isoformat(),
                    "last_used_at": auth.last_used_at.isoformat() if auth.last_used_at else None,
                }
                for auth in authenticators
            ]
        })

Các điểm cuối API

REST API của chúng tôi cung cấp hỗ trợ WebAuthn đầy đủ cho ứng dụng di động:

Điểm cuốiPhương thứcMô tả
/api/webauthn/register/options/GETLấy thử thách đăng ký
/api/webauthn/register/complete/POSTHoàn thành đăng ký
/api/webauthn/authenticate/options/GETLấy thử thách xác thực
/api/webauthn/verify/POSTXác minh thông tin xác thực cho 2FA
/api/webauthn/GETLiệt kê passkeys đã đăng ký
/api/webauthn/<id>/PATCHĐổi tên passkey
/api/webauthn/<id>/DELETEXóa passkey

Cân nhắc bảo mật

Mã khôi phục

Khi người dùng đăng ký authenticator đầu tiên (passkey hoặc TOTP), chúng tôi tự động tạo mã khôi phục. Các mã sử dụng một lần này có thể được sử dụng nếu tất cả các phương thức xác thực khác không khả dụng:

1
2
if Authenticator.objects.filter(user=request.user).count() == 1:
    auto_generate_recovery_codes(request._request)

Ngăn chặn khóa tài khoản

Người dùng không thể xóa passkey cuối cùng nếu điều đó khiến họ không có bất kỳ phương thức xác thực hai yếu tố nào:

1
2
3
4
if not adapter.can_delete_authenticator(authenticator):
    return Response({
        "message": "Không thể xóa - bạn phải có ít nhất một phương thức xác thực"
    }, status=400)

Giám sát

Chúng tôi theo dõi việc sử dụng passkey thông qua số liệu Datadog để giám sát bảo mật:

1
2
3
increment("webauthn.registration.success")
increment("webauthn.verify.success")
increment("webauthn.verify.failed")

Hỗ trợ trình duyệt

WebAuthn được hỗ trợ trong tất cả các trình duyệt hiện đại:

  • Chrome 67+
  • Firefox 60+
  • Safari 13+
  • Edge 79+
  • Mobile Chrome, Safari, Firefox

Đối với các trình duyệt cũ hơn, người dùng vẫn có thể sử dụng TOTP (ứng dụng authenticator) hoặc mã khôi phục.

Trải nghiệm người dùng

Thêm passkey chỉ mất vài giây:

  1. Đi đến Cài đặt → Bảo mật → Xác thực hai yếu tố
  2. Nhấp Thêm Passkey
  3. Đặt tên thiết bị của bạn (ví dụ: “iPhone 15”)
  4. Xác thực với Face ID / Touch ID / Windows Hello
  5. Xong! Passkey của bạn đã được đăng ký

Các lần đăng nhập trong tương lai chỉ yêu cầu xác nhận sinh trắc học - không cần gõ mật khẩu hoặc sao chép mã từ ứng dụng authenticator.

Tại sao chúng tôi chọn Passkeys

Phương thứcRủi ro lừa đảoTrải nghiệm người dùngKhôi phục
Mật khẩuCaoKém (quên, yếu)Đặt lại email
SMS 2FATrung bình (SIM swap)Tạm đượcSố điện thoại
Ứng dụng TOTPThấpNhập mã thủ côngKhóa dự phòng
PasskeysRất thấpXuất sắcMã khôi phục

Passkeys đại diện cho tương lai của xác thực. Chúng đã được hỗ trợ bởi các nền tảng Apple, Google và Microsoft, làm cho chúng có thể tiếp cận được với gần như tất cả người dùng của chúng tôi.


Sẵn sàng không dùng mật khẩu? Bật passkeys trong cài đặt bảo mật của bạn!