SDK quản trị Firebase cung cấp API Auth.importUsers()
để nhập hàng loạt người dùng vào Xác thực Firebase với các đặc quyền nâng cao. Mặc dù tính năng này cũng có sẵn trong Firebase CLI , nhưng SDK quản trị cho phép bạn tải lên người dùng hiện có từ hệ thống xác thực bên ngoài hoặc dự án Firebase khác theo chương trình mà không cần phải tạo tệp CSV hoặc JSON trung gian.
API nhập người dùng cung cấp các ưu điểm sau:
- Khả năng di chuyển người dùng từ hệ thống xác thực bên ngoài bằng cách sử dụng một thuật toán băm mật khẩu khác.
- Khả năng di chuyển người dùng từ một dự án Firebase khác.
- Tối ưu hóa cho hoạt động nhập hàng loạt nhanh chóng và hiệu quả. Thao tác này xử lý người dùng mà không cần kiểm tra xem có trùng lặp
uid
,email
,phoneNumber
hay không. - Khả năng di chuyển hiện có hoặc tạo người dùng OAuth mới (Google, Facebook, v.v.).
- Khả năng nhập hàng loạt người dùng có yêu cầu tùy chỉnh trực tiếp.
Cách sử dụng
Có thể nhập tối đa 1000 người dùng trong một lệnh gọi API. Lưu ý rằng thao tác này được tối ưu hóa về tốc độ và không kiểm tra uid
, email
, phoneNumber
và trùng lặp số nhận dạng duy nhất khác. Việc nhập một người dùng va chạm với một uid
hiện có sẽ thay thế người dùng hiện tại. Nhập một người dùng với bất kỳ trường nào khác bị trùng lặp (ví dụ: email
) sẽ dẫn đến một người dùng bổ sung có cùng giá trị. Do đó, khi bạn sử dụng API này, bạn phải đảm bảo rằng bạn không trùng lặp bất kỳ trường duy nhất nào.
Node.js
// Up to 1000 users can be imported at once.
const userImportRecords = [
{
uid: 'uid1',
email: 'user1@example.com',
passwordHash: Buffer.from('passwordHash1'),
passwordSalt: Buffer.from('salt1'),
},
{
uid: 'uid2',
email: 'user2@example.com',
passwordHash: Buffer.from('passwordHash2'),
passwordSalt: Buffer.from('salt2'),
},
//...
];
Java
// Up to 1000 users can be imported at once.
List<ImportUserRecord> users = new ArrayList<>();
users.add(ImportUserRecord.builder()
.setUid("uid1")
.setEmail("user1@example.com")
.setPasswordHash("passwordHash1".getBytes())
.setPasswordSalt("salt1".getBytes())
.build());
users.add(ImportUserRecord.builder()
.setUid("uid2")
.setEmail("user2@example.com")
.setPasswordHash("passwordHash2".getBytes())
.setPasswordSalt("salt2".getBytes())
.build());
Python
# Up to 1000 users can be imported at once.
users = [
auth.ImportUserRecord(
uid='uid1',
email='user1@example.com',
password_hash=b'password_hash_1',
password_salt=b'salt1'
),
auth.ImportUserRecord(
uid='uid2',
email='user2@example.com',
password_hash=b'password_hash_2',
password_salt=b'salt2'
),
]
Đi
// Up to 1000 users can be imported at once.
var users []*auth.UserToImport
users = append(users, (&auth.UserToImport{}).
UID("uid1").
Email("user1@example.com").
PasswordHash([]byte("passwordHash1")).
PasswordSalt([]byte("salt1")))
users = append(users, (&auth.UserToImport{}).
UID("uid2").
Email("user2@example.com").
PasswordHash([]byte("passwordHash2")).
PasswordSalt([]byte("salt2")))
C#
// Up to 1000 users can be imported at once.
var users = new List<ImportUserRecordArgs>()
{
new ImportUserRecordArgs()
{
Uid = "uid1",
Email = "user1@example.com",
PasswordHash = Encoding.ASCII.GetBytes("passwordHash1"),
PasswordSalt = Encoding.ASCII.GetBytes("salt1"),
},
new ImportUserRecordArgs()
{
Uid = "uid2",
Email = "user2@example.com",
PasswordHash = Encoding.ASCII.GetBytes("passwordHash2"),
PasswordSalt = Encoding.ASCII.GetBytes("salt2"),
},
};
Trong ví dụ này, các tùy chọn băm được chỉ định để giúp Firebase xác thực an toàn những người dùng này vào lần tiếp theo họ cố gắng đăng nhập bằng Xác thực Firebase. Khi đăng nhập thành công, Firebase băm lại mật khẩu của người dùng bằng thuật toán băm Firebase nội bộ. Tìm hiểu thêm về các trường bắt buộc cho mỗi thuật toán bên dưới.
Xác thực Firebase cố gắng tải lên toàn bộ danh sách người dùng được cung cấp ngay cả khi xảy ra lỗi dành riêng cho người dùng. Thao tác trả về một kết quả với bản tóm tắt các lần nhập thành công và không thành công. Chi tiết lỗi được trả lại cho mỗi lần nhập người dùng không thành công.
Node.js
getAuth()
.importUsers(userImportRecords, {
hash: {
algorithm: 'HMAC_SHA256',
key: Buffer.from('secretKey'),
},
})
.then((userImportResult) => {
// The number of successful imports is determined via: userImportResult.successCount.
// The number of failed imports is determined via: userImportResult.failureCount.
// To get the error details.
userImportResult.errors.forEach((indexedError) => {
// The corresponding user that failed to upload.
console.log(
'Error ' + indexedError.index,
' failed to import: ',
indexedError.error
);
});
})
.catch((error) => {
// Some unrecoverable error occurred that prevented the operation from running.
});
Java
UserImportOptions options = UserImportOptions.withHash(
HmacSha256.builder()
.setKey("secretKey".getBytes())
.build());
try {
UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
System.out.println("Successfully imported " + result.getSuccessCount() + " users");
System.out.println("Failed to import " + result.getFailureCount() + " users");
for (ErrorInfo indexedError : result.getErrors()) {
System.out.println("Failed to import user at index: " + indexedError.getIndex()
+ " due to error: " + indexedError.getReason());
}
} catch (FirebaseAuthException e) {
// Some unrecoverable error occurred that prevented the operation from running.
}
Python
hash_alg = auth.UserImportHash.hmac_sha256(key=b'secret_key')
try:
result = auth.import_users(users, hash_alg=hash_alg)
print('Successfully imported {0} users. Failed to import {1} users.'.format(
result.success_count, result.failure_count))
for err in result.errors:
print('Failed to import {0} due to {1}'.format(users[err.index].uid, err.reason))
except exceptions.FirebaseError:
# Some unrecoverable error occurred that prevented the operation from running.
pass
Đi
client, err := app.Auth(ctx)
if err != nil {
log.Fatalln("Error initializing Auth client", err)
}
h := hash.HMACSHA256{
Key: []byte("secretKey"),
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
log.Fatalln("Unrecoverable error prevented the operation from running", err)
}
log.Printf("Successfully imported %d users\n", result.SuccessCount)
log.Printf("Failed to import %d users\n", result.FailureCount)
for _, e := range result.Errors {
log.Printf("Failed to import user at index: %d due to error: %s\n", e.Index, e.Reason)
}
C#
var options = new UserImportOptions()
{
Hash = new HmacSha256()
{
Key = Encoding.ASCII.GetBytes("secretKey"),
},
};
try
{
UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
Console.WriteLine($"Successfully imported {result.SuccessCount} users");
Console.WriteLine($"Failed to import {result.FailureCount} users");
foreach (ErrorInfo indexedError in result.Errors)
{
Console.WriteLine($"Failed to import user at index: {indexedError.Index}"
+ $" due to error: {indexedError.Reason}");
}
}
catch (FirebaseAuthException)
{
// Some unrecoverable error occurred that prevented the operation from running.
}
Nếu không cần băm mật khẩu (số điện thoại, người dùng mã thông báo tùy chỉnh, người dùng OAuth, v.v.), không cung cấp tùy chọn băm.
Nhập người dùng bằng mật khẩu băm Firebase scrypt
Theo mặc định, Firebase sử dụng phiên bản Firebase đã sửa đổi của thuật toán băm scrypt để lưu trữ mật khẩu. Nhập mật khẩu được băm bằng scrypt đã sửa đổi rất hữu ích cho việc di chuyển người dùng từ một dự án Firebase hiện có khác. Để làm được như vậy, các thông số bên trong cần phải được xác định cho dự án ban đầu.
Firebase tạo các tham số băm mật khẩu duy nhất cho mỗi dự án Firebase. Để truy cập các tham số này, hãy điều hướng đến tab Người dùng trong bảng điều khiển Firebase và chọn Tham số băm mật khẩu từ menu thả xuống ở góc trên bên phải của danh sách người dùng trong bảng.
Các thông số cần thiết để xây dựng các tùy chọn băm cho thuật toán này bao gồm:
-
key
: khóa người ký thường được cung cấp trong mã hóa base64. -
saltSeparator
: bộ tách muối thường được cung cấp trong mã hóa base64 (tùy chọn). -
rounds
: số vòng dùng để băm mật khẩu. memoryCost
: chi phí bộ nhớ cần thiết cho thuật toán này.
Node.js
getAuth()
.importUsers(
[
{
uid: 'some-uid',
email: 'user@example.com',
// Must be provided in a byte buffer.
passwordHash: Buffer.from('base64-password-hash', 'base64'),
// Must be provided in a byte buffer.
passwordSalt: Buffer.from('base64-salt', 'base64'),
},
],
{
hash: {
algorithm: 'SCRYPT',
// All the parameters below can be obtained from the Firebase Console's users section.
// Must be provided in a byte buffer.
key: Buffer.from('base64-secret', 'base64'),
saltSeparator: Buffer.from('base64SaltSeparator', 'base64'),
rounds: 8,
memoryCost: 14,
},
}
)
.then((results) => {
results.errors.forEach((indexedError) => {
console.log(`Error importing user ${indexedError.index}`);
});
})
.catch((error) => {
console.log('Error importing users :', error);
});
Java
try {
List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
.setUid("some-uid")
.setEmail("user@example.com")
.setPasswordHash(BaseEncoding.base64().decode("password-hash"))
.setPasswordSalt(BaseEncoding.base64().decode("salt"))
.build());
UserImportOptions options = UserImportOptions.withHash(
Scrypt.builder()
// All the parameters below can be obtained from the Firebase Console's "Users"
// section. Base64 encoded parameters must be decoded into raw bytes.
.setKey(BaseEncoding.base64().decode("base64-secret"))
.setSaltSeparator(BaseEncoding.base64().decode("base64-salt-separator"))
.setRounds(8)
.setMemoryCost(14)
.build());
UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
for (ErrorInfo indexedError : result.getErrors()) {
System.out.println("Failed to import user: " + indexedError.getReason());
}
} catch (FirebaseAuthException e) {
System.out.println("Error importing users: " + e.getMessage());
}
Python
users = [
auth.ImportUserRecord(
uid='some-uid',
email='user@example.com',
password_hash=base64.urlsafe_b64decode('password_hash'),
password_salt=base64.urlsafe_b64decode('salt')
),
]
# All the parameters below can be obtained from the Firebase Console's "Users"
# section. Base64 encoded parameters must be decoded into raw bytes.
hash_alg = auth.UserImportHash.scrypt(
key=base64.b64decode('base64_secret'),
salt_separator=base64.b64decode('base64_salt_separator'),
rounds=8,
memory_cost=14
)
try:
result = auth.import_users(users, hash_alg=hash_alg)
for err in result.errors:
print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
print('Error importing users:', error)
Đi
b64URLdecode := func(s string) []byte {
b, err := base64.URLEncoding.DecodeString(s)
if err != nil {
log.Fatalln("Failed to decode string", err)
}
return b
}
b64Stddecode := func(s string) []byte {
b, err := base64.StdEncoding.DecodeString(s)
if err != nil {
log.Fatalln("Failed to decode string", err)
}
return b
}
// Users retrieved from Firebase Auth's backend need to be base64URL decoded
users := []*auth.UserToImport{
(&auth.UserToImport{}).
UID("some-uid").
Email("user@example.com").
PasswordHash(b64URLdecode("password-hash")).
PasswordSalt(b64URLdecode("salt")),
}
// All the parameters below can be obtained from the Firebase Console's "Users"
// section. Base64 encoded parameters must be decoded into raw bytes.
h := hash.Scrypt{
Key: b64Stddecode("base64-secret"),
SaltSeparator: b64Stddecode("base64-salt-separator"),
Rounds: 8,
MemoryCost: 14,
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
log.Println("Failed to import user", e.Reason)
}
C#
try
{
var users = new List<ImportUserRecordArgs>()
{
new ImportUserRecordArgs()
{
Uid = "some-uid",
Email = "user@example.com",
PasswordHash = Encoding.ASCII.GetBytes("password-hash"),
PasswordSalt = Encoding.ASCII.GetBytes("salt"),
},
};
var options = new UserImportOptions()
{
// All the parameters below can be obtained from the Firebase Console's "Users"
// section. Base64 encoded parameters must be decoded into raw bytes.
Hash = new Scrypt()
{
Key = Encoding.ASCII.GetBytes("base64-secret"),
SaltSeparator = Encoding.ASCII.GetBytes("base64-salt-separator"),
Rounds = 8,
MemoryCost = 14,
},
};
UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
foreach (ErrorInfo indexedError in result.Errors)
{
Console.WriteLine($"Failed to import user: {indexedError.Reason}");
}
}
catch (FirebaseAuthException e)
{
Console.WriteLine($"Error importing users: {e.Message}");
}
Nhập người dùng với mật khẩu băm tiêu chuẩn scrypt
Xác thực Firebase hỗ trợ thuật toán mã hóa tiêu chuẩn cũng như phiên bản đã sửa đổi (ở trên). Đối với thuật toán scrypt tiêu chuẩn, các tham số băm sau là bắt buộc:
-
memoryCost
: chi phí CPU / bộ nhớ của thuật toán băm. -
parallelization
hóa: sự song song hóa của thuật toán băm. -
blockSize
: kích thước khối (thường là 8) của thuật toán băm. derivedKeyLength
: Độ dài khóa dẫn xuất của thuật toán băm
Node.js
getAuth()
.importUsers(
[
{
uid: 'some-uid',
email: 'user@example.com',
// Must be provided in a byte buffer.
passwordHash: Buffer.from('password-hash'),
// Must be provided in a byte buffer.
passwordSalt: Buffer.from('salt'),
},
],
{
hash: {
algorithm: 'STANDARD_SCRYPT',
memoryCost: 1024,
parallelization: 16,
blockSize: 8,
derivedKeyLength: 64,
},
}
)
.then((results) => {
results.errors.forEach((indexedError) => {
console.log(`Error importing user ${indexedError.index}`);
});
})
.catch((error) => {
console.log('Error importing users :', error);
});
Java
try {
List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
.setUid("some-uid")
.setEmail("user@example.com")
.setPasswordHash("password-hash".getBytes())
.setPasswordSalt("salt".getBytes())
.build());
UserImportOptions options = UserImportOptions.withHash(
StandardScrypt.builder()
.setMemoryCost(1024)
.setParallelization(16)
.setBlockSize(8)
.setDerivedKeyLength(64)
.build());
UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
for (ErrorInfo indexedError : result.getErrors()) {
System.out.println("Failed to import user: " + indexedError.getReason());
}
} catch (FirebaseAuthException e) {
System.out.println("Error importing users: " + e.getMessage());
}
Python
users = [
auth.ImportUserRecord(
uid='some-uid',
email='user@example.com',
password_hash=b'password_hash',
password_salt=b'salt'
),
]
hash_alg = auth.UserImportHash.standard_scrypt(
memory_cost=1024, parallelization=16, block_size=8, derived_key_length=64)
try:
result = auth.import_users(users, hash_alg=hash_alg)
for err in result.errors:
print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
print('Error importing users:', error)
Đi
users := []*auth.UserToImport{
(&auth.UserToImport{}).
UID("some-uid").
Email("user@example.com").
PasswordHash([]byte("password-hash")).
PasswordSalt([]byte("salt")),
}
h := hash.StandardScrypt{
MemoryCost: 1024,
Parallelization: 16,
BlockSize: 8,
DerivedKeyLength: 64,
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
log.Println("Failed to import user", e.Reason)
}
C#
try
{
var users = new List<ImportUserRecordArgs>()
{
new ImportUserRecordArgs()
{
Uid = "some-uid",
Email = "user@example.com",
PasswordHash = Encoding.ASCII.GetBytes("password-hash"),
PasswordSalt = Encoding.ASCII.GetBytes("salt"),
},
};
var options = new UserImportOptions()
{
Hash = new StandardScrypt()
{
MemoryCost = 1024,
Parallelization = 16,
BlockSize = 8,
DerivedKeyLength = 64,
},
};
UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
foreach (ErrorInfo indexedError in result.Errors)
{
Console.WriteLine($"Failed to import user: {indexedError.Reason}");
}
}
catch (FirebaseAuthException e)
{
Console.WriteLine($"Error importing users: {e.Message}");
}
Nhập người dùng với mật khẩu được băm HMAC
Các thuật toán băm HMAC bao gồm: HMAC_MD5
, HMAC_SHA1
, HMAC_SHA256
và HMAC_SHA512
. Đối với các thuật toán băm này, bạn phải cung cấp khóa trình ký băm.
Node.js
getAuth()
.importUsers(
[
{
uid: 'some-uid',
email: 'user@example.com',
// Must be provided in a byte buffer.
passwordHash: Buffer.from('password-hash'),
// Must be provided in a byte buffer.
passwordSalt: Buffer.from('salt'),
},
],
{
hash: {
algorithm: 'HMAC_SHA256',
// Must be provided in a byte buffer.
key: Buffer.from('secret'),
},
}
)
.then((results) => {
results.errors.forEach((indexedError) => {
console.log(`Error importing user ${indexedError.index}`);
});
})
.catch((error) => {
console.log('Error importing users :', error);
});
Java
try {
List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
.setUid("some-uid")
.setEmail("user@example.com")
.setPasswordHash("password-hash".getBytes())
.setPasswordSalt("salt".getBytes())
.build());
UserImportOptions options = UserImportOptions.withHash(
HmacSha256.builder()
.setKey("secret".getBytes())
.build());
UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
for (ErrorInfo indexedError : result.getErrors()) {
System.out.println("Failed to import user: " + indexedError.getReason());
}
} catch (FirebaseAuthException e) {
System.out.println("Error importing users: " + e.getMessage());
}
Python
users = [
auth.ImportUserRecord(
uid='some-uid',
email='user@example.com',
password_hash=b'password_hash',
password_salt=b'salt'
),
]
hash_alg = auth.UserImportHash.hmac_sha256(key=b'secret')
try:
result = auth.import_users(users, hash_alg=hash_alg)
for err in result.errors:
print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
print('Error importing users:', error)
Đi
users := []*auth.UserToImport{
(&auth.UserToImport{}).
UID("some-uid").
Email("user@example.com").
PasswordHash([]byte("password-hash")).
PasswordSalt([]byte("salt")),
}
h := hash.HMACSHA256{
Key: []byte("secret"),
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
log.Println("Failed to import user", e.Reason)
}
C#
try
{
var users = new List<ImportUserRecordArgs>()
{
new ImportUserRecordArgs()
{
Uid = "some-uid",
Email = "user@example.com",
PasswordHash = Encoding.ASCII.GetBytes("password-hash"),
PasswordSalt = Encoding.ASCII.GetBytes("salt"),
},
};
var options = new UserImportOptions()
{
Hash = new HmacSha256()
{
Key = Encoding.ASCII.GetBytes("secret"),
},
};
UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
foreach (ErrorInfo indexedError in result.Errors)
{
Console.WriteLine($"Failed to import user: {indexedError.Reason}");
}
}
catch (FirebaseAuthException e)
{
Console.WriteLine($"Error importing users: {e.Message}");
}
Nhập người dùng có mật khẩu băm MD5, SHA và PBKDF
Các thuật toán băm MD5, SHA và PBKDF bao gồm: MD5
, SHA1
, SHA256
, SHA512
, PBKDF_SHA1
và PBKDF2_SHA256
. Đối với các thuật toán băm này, bạn phải cung cấp số vòng (từ 0 đến 8192 đối với MD5
, từ 1 đến 8192 đối với SHA1
, SHA256
và SHA512
và từ 0 đến 120000 đối với PBKDF_SHA1
và PBKDF2_SHA256
) được sử dụng để băm mật khẩu.
Node.js
getAuth()
.importUsers(
[
{
uid: 'some-uid',
email: 'user@example.com',
// Must be provided in a byte buffer.
passwordHash: Buffer.from('password-hash'),
// Must be provided in a byte buffer.
passwordSalt: Buffer.from('salt'),
},
],
{
hash: {
algorithm: 'PBKDF2_SHA256',
rounds: 100000,
},
}
)
.then((results) => {
results.errors.forEach((indexedError) => {
console.log(`Error importing user ${indexedError.index}`);
});
})
.catch((error) => {
console.log('Error importing users :', error);
});
Java
try {
List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
.setUid("some-uid")
.setEmail("user@example.com")
.setPasswordHash("password-hash".getBytes())
.setPasswordSalt("salt".getBytes())
.build());
UserImportOptions options = UserImportOptions.withHash(
Pbkdf2Sha256.builder()
.setRounds(100000)
.build());
UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
for (ErrorInfo indexedError : result.getErrors()) {
System.out.println("Failed to import user: " + indexedError.getReason());
}
} catch (FirebaseAuthException e) {
System.out.println("Error importing users: " + e.getMessage());
}
Python
users = [
auth.ImportUserRecord(
uid='some-uid',
email='user@example.com',
password_hash=b'password_hash',
password_salt=b'salt'
),
]
hash_alg = auth.UserImportHash.pbkdf2_sha256(rounds=100000)
try:
result = auth.import_users(users, hash_alg=hash_alg)
for err in result.errors:
print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
print('Error importing users:', error)
Đi
users := []*auth.UserToImport{
(&auth.UserToImport{}).
UID("some-uid").
Email("user@example.com").
PasswordHash([]byte("password-hash")).
PasswordSalt([]byte("salt")),
}
h := hash.PBKDF2SHA256{
Rounds: 100000,
}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
log.Println("Failed to import user", e.Reason)
}
C#
try
{
var users = new List<ImportUserRecordArgs>()
{
new ImportUserRecordArgs()
{
Uid = "some-uid",
Email = "user@example.com",
PasswordHash = Encoding.ASCII.GetBytes("password-hash"),
PasswordSalt = Encoding.ASCII.GetBytes("salt"),
},
};
var options = new UserImportOptions()
{
Hash = new Pbkdf2Sha256()
{
Rounds = 100000,
},
};
UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
foreach (ErrorInfo indexedError in result.Errors)
{
Console.WriteLine($"Failed to import user: {indexedError.Reason}");
}
}
catch (FirebaseAuthException e)
{
Console.WriteLine($"Error importing users: {e.Message}");
}
Nhập người dùng với mật khẩu được băm BCRYPT
Đối với mật khẩu được băm BCRYPT, không yêu cầu tham số băm bổ sung cũng như muối mật khẩu cho mỗi người dùng.
Node.js
getAuth()
.importUsers(
[
{
uid: 'some-uid',
email: 'user@example.com',
// Must be provided in a byte buffer.
passwordHash: Buffer.from('password-hash'),
},
],
{
hash: {
algorithm: 'BCRYPT',
},
}
)
.then((results) => {
results.errors.forEach((indexedError) => {
console.log(`Error importing user ${indexedError.index}`);
});
})
.catch((error) => {
console.log('Error importing users :', error);
});
Java
try {
List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
.setUid("some-uid")
.setEmail("user@example.com")
.setPasswordHash("password-hash".getBytes())
.setPasswordSalt("salt".getBytes())
.build());
UserImportOptions options = UserImportOptions.withHash(Bcrypt.getInstance());
UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
for (ErrorInfo indexedError : result.getErrors()) {
System.out.println("Failed to import user: " + indexedError.getReason());
}
} catch (FirebaseAuthException e) {
System.out.println("Error importing users: " + e.getMessage());
}
Python
users = [
auth.ImportUserRecord(
uid='some-uid',
email='user@example.com',
password_hash=b'password_hash',
password_salt=b'salt'
),
]
hash_alg = auth.UserImportHash.bcrypt()
try:
result = auth.import_users(users, hash_alg=hash_alg)
for err in result.errors:
print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
print('Error importing users:', error)
Đi
users := []*auth.UserToImport{
(&auth.UserToImport{}).
UID("some-uid").
Email("user@example.com").
PasswordHash([]byte("password-hash")).
PasswordSalt([]byte("salt")),
}
h := hash.Bcrypt{}
result, err := client.ImportUsers(ctx, users, auth.WithHash(h))
if err != nil {
log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
log.Println("Failed to import user", e.Reason)
}
C#
try
{
var users = new List<ImportUserRecordArgs>()
{
new ImportUserRecordArgs()
{
Uid = "some-uid",
Email = "user@example.com",
PasswordHash = Encoding.ASCII.GetBytes("password-hash"),
PasswordSalt = Encoding.ASCII.GetBytes("salt"),
},
};
var options = new UserImportOptions()
{
Hash = new Bcrypt(),
};
UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users, options);
foreach (ErrorInfo indexedError in result.Errors)
{
Console.WriteLine($"Failed to import user: {indexedError.Reason}");
}
}
catch (FirebaseAuthException e)
{
Console.WriteLine($"Error importing users: {e.Message}");
}
Nhập người dùng với mật khẩu được băm Argon2
Bạn có thể nhập các bản ghi người dùng có mật khẩu băm Argon2 bằng cách xây dựng một đối tượng băm Argon2
. Lưu ý rằng điều này hiện chỉ được hỗ trợ trong SDK Java dành cho quản trị viên.
Các thông số cần thiết để xây dựng các tùy chọn băm cho thuật toán này bao gồm:
-
hashLengthBytes
: độ dài băm mong muốn tính bằng byte, được cung cấp dưới dạng số nguyên -
hashType
: biến thể Argon2 sẽ được sử dụng (ARGON2_D
,ARGON2_ID
,ARGON2_I
) -
parallelism
: mức độ song song, được cung cấp dưới dạng số nguyên. Phải từ 1 đến 16 (bao gồm) - số
iterations
: số lần lặp lại để thực hiện, được cung cấp dưới dạng số nguyên. Phải từ 1 đến 16 (bao gồm) -
memoryCostKib
: chi phí bộ nhớ cần thiết cho thuật toán này tính bằng kibibyte, phải nhỏ hơn 32768. -
version
: phiên bản của thuật toán Argon2 (VERSION_10
hoặcVERSION_13
). Tùy chọn, mặc định là VERSION_13 nếu không được chỉ định. Dữ liệu
associatedData
: dữ liệu được liên kết bổ sung, được cung cấp dưới dạng một mảng byte, được nối vào giá trị băm để cung cấp một lớp bảo mật bổ sung. Tùy chọn, dữ liệu này được mã hóa base64 trước khi được gửi đến API.
Java
try {
List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
.setUid("some-uid")
.setEmail("user@example.com")
.setPasswordHash("password-hash".getBytes())
.setPasswordSalt("salt".getBytes())
.build());
UserImportOptions options = UserImportOptions.withHash(
Argon2.builder()
.setHashLengthBytes(512)
.setHashType(Argon2HashType.ARGON2_ID)
.setParallelism(8)
.setIterations(16)
.setMemoryCostKib(2048)
.setVersion(Argon2Version.VERSION_10)
.setAssociatedData("associated-data".getBytes())
.build());
UserImportResult result = FirebaseAuth.getInstance().importUsers(users, options);
for (ErrorInfo indexedError : result.getErrors()) {
System.out.println("Failed to import user: " + indexedError.getReason());
}
} catch (FirebaseAuthException e) {
System.out.println("Error importing users: " + e.getMessage());
}
Nhập người dùng không có mật khẩu
Bạn có thể nhập người dùng mà không cần mật khẩu. Người dùng không có mật khẩu có thể được nhập kết hợp với người dùng có nhà cung cấp OAuth, xác nhận quyền sở hữu tùy chỉnh và số điện thoại, v.v.
Node.js
getAuth()
.importUsers([
{
uid: 'some-uid',
displayName: 'John Doe',
email: 'johndoe@gmail.com',
photoURL: 'http://www.example.com/12345678/photo.png',
emailVerified: true,
phoneNumber: '+11234567890',
// Set this user as admin.
customClaims: { admin: true },
// User with Google provider.
providerData: [
{
uid: 'google-uid',
email: 'johndoe@gmail.com',
displayName: 'John Doe',
photoURL: 'http://www.example.com/12345678/photo.png',
providerId: 'google.com',
},
],
},
])
.then((results) => {
results.errors.forEach((indexedError) => {
console.log(`Error importing user ${indexedError.index}`);
});
})
.catch((error) => {
console.log('Error importing users :', error);
});
Java
try {
List<ImportUserRecord> users = Collections.singletonList(ImportUserRecord.builder()
.setUid("some-uid")
.setDisplayName("John Doe")
.setEmail("johndoe@gmail.com")
.setPhotoUrl("http://www.example.com/12345678/photo.png")
.setEmailVerified(true)
.setPhoneNumber("+11234567890")
.putCustomClaim("admin", true) // set this user as admin
.addUserProvider(UserProvider.builder() // user with Google provider
.setUid("google-uid")
.setEmail("johndoe@gmail.com")
.setDisplayName("John Doe")
.setPhotoUrl("http://www.example.com/12345678/photo.png")
.setProviderId("google.com")
.build())
.build());
UserImportResult result = FirebaseAuth.getInstance().importUsers(users);
for (ErrorInfo indexedError : result.getErrors()) {
System.out.println("Failed to import user: " + indexedError.getReason());
}
} catch (FirebaseAuthException e) {
System.out.println("Error importing users: " + e.getMessage());
}
Python
users = [
auth.ImportUserRecord(
uid='some-uid',
display_name='John Doe',
email='johndoe@gmail.com',
photo_url='http://www.example.com/12345678/photo.png',
email_verified=True,
phone_number='+11234567890',
custom_claims={'admin': True}, # set this user as admin
provider_data=[ # user with Google provider
auth.UserProvider(
uid='google-uid',
email='johndoe@gmail.com',
display_name='John Doe',
photo_url='http://www.example.com/12345678/photo.png',
provider_id='google.com'
)
],
),
]
try:
result = auth.import_users(users)
for err in result.errors:
print('Failed to import user:', err.reason)
except exceptions.FirebaseError as error:
print('Error importing users:', error)
Đi
users := []*auth.UserToImport{
(&auth.UserToImport{}).
UID("some-uid").
DisplayName("John Doe").
Email("johndoe@gmail.com").
PhotoURL("http://www.example.com/12345678/photo.png").
EmailVerified(true).
PhoneNumber("+11234567890").
CustomClaims(map[string]interface{}{"admin": true}). // set this user as admin
ProviderData([]*auth.UserProvider{ // user with Google provider
{
UID: "google-uid",
Email: "johndoe@gmail.com",
DisplayName: "John Doe",
PhotoURL: "http://www.example.com/12345678/photo.png",
ProviderID: "google.com",
},
}),
}
result, err := client.ImportUsers(ctx, users)
if err != nil {
log.Fatalln("Error importing users", err)
}
for _, e := range result.Errors {
log.Println("Failed to import user", e.Reason)
}
C#
try
{
var users = new List<ImportUserRecordArgs>()
{
new ImportUserRecordArgs()
{
Uid = "some-uid",
DisplayName = "John Doe",
Email = "johndoe@gmail.com",
PhotoUrl = "http://www.example.com/12345678/photo.png",
EmailVerified = true,
PhoneNumber = "+11234567890",
CustomClaims = new Dictionary<string, object>()
{
{ "admin", true }, // set this user as admin
},
UserProviders = new List<UserProvider>
{
new UserProvider() // user with Google provider
{
Uid = "google-uid",
Email = "johndoe@gmail.com",
DisplayName = "John Doe",
PhotoUrl = "http://www.example.com/12345678/photo.png",
ProviderId = "google.com",
},
},
},
};
UserImportResult result = await FirebaseAuth.DefaultInstance.ImportUsersAsync(users);
foreach (ErrorInfo indexedError in result.Errors)
{
Console.WriteLine($"Failed to import user: {indexedError.Reason}");
}
}
catch (FirebaseAuthException e)
{
Console.WriteLine($"Error importing users: {e.Message}");
}