Đăng nhập an toàn trên ứng dụng di động: lưu token ở đâu cho đúng?

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Sau khi người dùng đăng nhập, ứng dụng cần nhớ họ để không bắt nhập lại mật khẩu mỗi lần mở. Thông thường đó là token do máy chủ cấp. Nơi bạn cất token quyết định mức an toàn của tài khoản người dùng. Bài viết giải thích cách làm đúng cho người mới.

Đừng lưu mật khẩu trên máy

Nguyên tắc đầu tiên: ứng dụng không nên lưu mật khẩu của người dùng. Hãy gửi thông tin đăng nhập cho máy chủ qua kết nối an toàn, nhận về token đại diện cho phiên đăng nhập rồi chỉ lưu token này. Nếu cần mở khóa nhanh, hãy dùng sinh trắc học của thiết bị để bảo vệ quyền truy cập token thay vì lưu mật khẩu.

Các loại token thường gặp

  • Access token: thời hạn ngắn, gửi kèm mỗi yêu cầu API. Nếu bị lộ, thiệt hại giới hạn trong thời gian ngắn.
  • Refresh token: thời hạn dài hơn, chỉ dùng để xin access token mới. Cần bảo vệ cẩn thận hơn.

Nơi lưu token

Nơi lưuĐánh giá
shared_preferences, UserDefaults, AsyncStorageKhông mã hóa, không nên chứa token nhạy cảm
Tệp văn bản thường hoặc cơ sở dữ liệu không mã hóaKhông nên
Android Keystore, iOS KeychainKho lưu trữ an toàn do hệ điều hành cung cấp, nên dùng

Các framework đều có thư viện bọc kho lưu trữ an toàn: Flutter có flutter_secure_storage, Expo có expo-secure-store, React Native có các thư viện keychain tương ứng, native thì dùng trực tiếp Keychain và Keystore.

// Flutter
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

const storage = FlutterSecureStorage();

Future<void> saveTokens(String access, String refresh) async {
  await storage.write(key: 'access_token', value: access);
  await storage.write(key: 'refresh_token', value: refresh);
}

Future<String?> readAccessToken() => storage.read(key: 'access_token');

Future<void> logout() async {
  await storage.deleteAll();
}

Làm mới token tự động

Khi access token hết hạn, máy chủ trả mã 401. Ứng dụng nên dùng refresh token để xin token mới rồi thử lại yêu cầu ban đầu, hoàn toàn trong suốt với người dùng. Hãy đảm bảo nhiều yêu cầu cùng thất bại không kích hoạt nhiều lần làm mới đồng thời; dùng một khóa hoặc hàng đợi.

Giao tiếp an toàn

  1. Luôn dùng HTTPS cho mọi yêu cầu; không chấp nhận chứng chỉ không hợp lệ.
  2. Không đưa token vào đường dẫn URL, vì chúng có thể bị ghi vào nhật ký.
  3. Gửi token qua header Authorization.
  4. Cân nhắc ghim chứng chỉ (certificate pinning) cho ứng dụng nhạy cảm, nhưng cần có kế hoạch xử lý khi đổi chứng chỉ.

Đừng nhúng bí mật vào ứng dụng

Mã ứng dụng có thể bị dịch ngược. Khóa API bí mật, mật khẩu cơ sở dữ liệu hay khóa riêng của máy chủ không được nằm trong ứng dụng. Mọi thao tác cần bí mật nên thực hiện ở máy chủ. Khóa công khai dành cho khách hàng thì được phép, nhưng hãy giới hạn quyền của chúng ở phía nhà cung cấp.

Đăng xuất và hết hạn

  • Khi đăng xuất, xóa token khỏi máy và báo máy chủ thu hồi phiên.
  • Cho phép người dùng đăng xuất khỏi mọi thiết bị.
  • Xử lý trường hợp refresh token hết hạn bằng cách đưa người dùng về màn hình đăng nhập.
  • Xóa dữ liệu nhạy cảm đã lưu cục bộ khi đăng xuất.

Sinh trắc học

Xác thực bằng vân tay hoặc khuôn mặt giúp tăng tiện lợi: sau lần đăng nhập đầu, người dùng chỉ cần xác thực sinh trắc để mở khóa token đã lưu an toàn. Đây là lớp bảo vệ cục bộ chứ không thay thế xác thực với máy chủ.

Kết luận

Quy tắc ghi nhớ: không lưu mật khẩu, lưu token trong Keychain hoặc Keystore, dùng HTTPS, thời hạn ngắn cho access token và không nhúng bí mật vào ứng dụng. Làm đúng những điều này đã tránh được phần lớn lỗi bảo mật phổ biến.

Các thói quen bảo vệ tài khoản người dùng

  • Giới hạn số lần đăng nhập sai ở máy chủ để chống dò mật khẩu.
  • Cân nhắc xác thực hai yếu tố, nhất là với thao tác nhạy cảm.
  • Thông báo khi có đăng nhập từ thiết bị mới.
  • Không tiết lộ tài khoản có tồn tại hay không qua thông báo lỗi.
  • Dùng cơ chế đăng nhập của nền tảng hoặc nhà cung cấp danh tính uy tín khi có thể, thay vì tự xây mọi thứ.

Kiểm thử luồng xác thực

Luồng đăng nhập cần được kiểm thử kỹ vì lỗi ở đây ảnh hưởng mọi người dùng. Thử các tình huống: token hết hạn giữa chừng, làm mới token thất bại, mất mạng khi đang đăng nhập, đăng nhập trên hai thiết bị, đăng xuất rồi đăng nhập tài khoản khác. Kiểm tra rằng dữ liệu của tài khoản trước không còn hiển thị cho tài khoản sau.

Để hiểu cả phía ứng dụng lẫn phía máy chủ của xác thực, bạn có thể xem thêm các khóa học tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment