โครงสร้างข้อมูลผู้ใช้
ผู้ใช้คือเอนทิตีหลักในบริการข้อมูลระบุตัวตน ใน Logto ผู้ใช้จะมีข้อมูลการยืนยันตัวตนพื้นฐานตามโปรโตคอล OpenID Connect พร้อมกับข้อมูลที่กำหนดเอง
โปรไฟล์ผู้ใช้
ผู้ใช้แต่ละคนจะมีโปรไฟล์ที่ประกอบด้วย ข้อมูลผู้ใช้ทั้งหมด
ประกอบด้วยข้อมูลประเภทต่อไปนี้:
- ข้อมูลพื้นฐาน: คือข้อมูลพื้นฐานจากโปรไฟล์ผู้ใช้ เก็บคุณสมบัติอื่น ๆ ของ ผู้ใช้ ทั้งหมด ยกเว้น
identitiesทางโซเชียลและcustom_dataเช่น รหัสผู้ใช้ ชื่อผู้ใช้ อีเมล หมายเลขโทรศัพท์ และเวลาที่ผู้ใช้ลงชื่อเข้าใช้ล่าสุด - ข้อมูลระบุตัวตนทางโซเชียล: เก็บข้อมูลผู้ใช้ที่ได้รับจากการลงชื่อเข้าใช้ด้วยโซเชียล (เช่น ลงชื่อเข้าใช้ด้วยตัวเชื่อมต่อโซเชียล) เช่น Facebook, GitHub และ WeChat
- ข้อมูลที่กำหนดเอง: เก็บข้อมูลผู้ใช้เพิ่มเติมที่ไม่ได้อยู่ในคุณสมบัติผู้ใช้ที่กำหนดไว้ล่วงหน้า เช่น สีและภาษาที่ผู้ใช้ชื่นชอบ
ตัวอย่างข้อมูลผู้ใช้ที่ได้จากการลงชื่อเข้าใช้ Facebook:
{
"id": "iHXPuSb9eMzt",
"username": null,
"primaryEmail": null,
"primaryPhone": null,
"name": "John Doe",
"avatar": "https://example.com/avatar.png",
"customData": {
"preferences": {
"language": "en",
"color": "#f236c9"
}
},
"identities": {
"facebook": {
"userId": "106077000000000",
"details": {
"id": "106077000000000",
"name": "John Doe",
"email": "johndoe@logto.io",
"avatar": "https://example.com/avatar.png"
}
}
},
"lastSignInAt": 1655799453171,
"applicationId": "admin_console"
}
คุณสามารถค้นหาโปรไฟล์ผู้ใช้ได้โดยใช้ Logto Console หรือ Logto Management API เช่น GET /api/users/:userId
ข้อมูลพื้นฐาน
มาดูคุณสมบัติทั้งหมดใน ข้อมูลพื้นฐาน ของผู้ใช้กัน
id
id คือคีย์เฉพาะที่ใช้ระบุผู้ใช้ใน Logto โดยจะถูกสร้างขึ้นโดยอัตโนมัติ ใน Logto แบบ self-hosted คุณสามารถกำหนด id เองได้เมื่อสร้างผู้ใช้ผ่าน Management API เช่น เพื่อ คงรหัสผู้ใช้เดิมระหว่างการย้ายข้อมูล
username
username ใช้สำหรับลงชื่อเข้าใช้ด้วย username และรหัสผ่าน
ค่าของมันมาจากชื่อผู้ใช้ที่ผู้ใช้ลงทะเบียนครั้งแรก อาจเป็น null ได้ ค่าที่ไม่เป็น null ต้องไม่เกิน 128 ตัวอักษร ประกอบด้วยตัวอักษร ตัวเลข และขีดล่าง (_) เท่านั้น และต้องไม่ขึ้นต้นด้วยตัวเลข ตัวพิมพ์เล็ก/ใหญ่มีผลโดยค่าเริ่มต้น กฎเหล่านี้สามารถจำกัดเพิ่มเติมต่อ tenant ได้ด้วย นโยบายชื่อผู้ใช้
primary_email
primary_email คืออีเมลของผู้ใช้ ใช้สำหรับลงชื่อเข้าใช้ด้วยอีเมลและรหัสผ่าน / รหัสยืนยัน
ค่าของมันมักมาจากอีเมลที่ผู้ใช้ลงทะเบียนครั้งแรก อาจเป็น null ได้ ความยาวสูงสุด 128 ตัวอักษร
เฉพาะอีเมลที่ได้รับการยืนยันจากผู้ให้บริการข้อมูลระบุตัวตนทางโซเชียลหรือ enterprise SSO เท่านั้นที่สามารถซิงก์และบันทึกเป็น primary_email ได้
primary_phone
primary_phone คือหมายเลขโทรศัพท์ของผู้ใช้ ใช้สำหรับลงชื่อเข้าใช้ด้วยหมายเลขโทรศัพท์และรหัสผ่าน / รหัสยืนยันจาก SMS
ค่าของมันมักมาจากหมายเลขโทรศัพท์ที่ผู้ใช้ลงทะเบียนครั้งแรก อาจเป็น null ได้ ค่าที่ไม่เป็น null ต้องเป็นตัวเลขที่มี รหัสประเทศ นำหน้า (ไม่รวมเครื่องหมายบวก +)
เฉพาะหมายเลขโทรศัพท์ที่ได้รับการยืนยันจากผู้ให้บริการข้อมูลระบุตัวตนทางโซเชียลหรือ enterprise SSO เท่านั้นที่สามารถซิงก์และบันทึกเป็น primary_phone ได้
name
name คือชื่อเต็มของผู้ใช้ ความยาวสูงสุด 128 ตัวอักษร
avatar
avatar คือ URL ที่ชี้ไปยังรูปโปรไฟล์ของผู้ใช้ ความยาวสูงสุด 2048 ตัวอักษร
หากผู้ใช้ลงทะเบียนด้วยตัวเชื่อมต่อโซเชียล เช่น Google หรือ Facebook ค่านี้อาจได้มาจากข้อมูลผู้ใช้ทางโซเชียล
คุณสมบัตินี้จะถูกแมปกับ claim picture ในมาตรฐาน OpenID Connect
profile
profile เก็บ standard claims ของ OpenID Connect เพิ่มเติมที่ไม่ได้อยู่ในคุณสมบัติของผู้ใช้
สามารถดู type definition ได้ที่ ไฟล์นี้ ตัวอย่าง type definition:
type UserProfile = Partial<{
familyName: string;
givenName: string;
middleName: string;
nickname: string;
preferredUsername: string;
profile: string;
website: string;
gender: string;
birthdate: string;
zoneinfo: string;
locale: string;
address: Partial<{
formatted: string;
streetAddress: string;
locality: string;
region: string;
postalCode: string;
country: string;
}>;
}>;
Partial หมายถึงทุก property เป็น optional
ความแตกต่างเมื่อเทียบกับ standard claims อื่น ๆ คือ property ใน profile จะถูกใส่ใน ID token หรือ response ของ userinfo endpoint เฉพาะเมื่อค่าของมันไม่ว่างเปล่า ในขณะที่ standard claims อื่น ๆ จะคืนค่า null หากค่าว่างเปล่า
ข้อยกเว้นคือ claim preferred_username: เมื่อ preferredUsername ใน profile ว่างเปล่า claim จะ fallback ไปที่ username ของผู้ใช้ เพื่อให้ client ที่รองรับมาตรฐานได้รับค่าที่ใช้งานได้ทันที โดยค่าที่กำหนดใน preferredUsername จะมีลำดับความสำคัญสูงสุดเสมอหากตั้งไว้
application_id
ค่าของ application_id มาจากแอปพลิเคชันที่ผู้ใช้ลงชื่อเข้าใช้ครั้งแรก อาจเป็น null ได้
last_sign_in_at
last_sign_in_at คือ timestamp พร้อม timezone เมื่อผู้ใช้ลงชื่อเข้าใช้ครั้งล่าสุด
created_at
created_at คือ timestamp พร้อม timezone เมื่อผู้ใช้ลงทะเบียนบัญชี
updated_at
updated_at คือ timestamp พร้อม timezone เมื่อข้อมูลโปรไฟล์ผู้ใช้ถูกอัปเดตล่าสุด
has_password
has_password เป็นค่า boolean ที่ระบุว่าผู้ใช้มีรหัสผ่านหรือไม่ คุณสามารถดูและจัดการสถานะนี้ รวมถึงตั้งค่าหรือรีเซ็ตรหัสผ่านใหม่ได้ที่หน้า Console > User management
password_encrypted
password_encrypted ใช้เก็บรหัสผ่านที่เข้ารหัสของผู้ใช้
ค่าของมันมาจากรหัสผ่านที่ผู้ใช้ลงทะเบียนครั้งแรก อาจเป็น null ได้ หากไม่เป็น null เนื้อหาก่อนเข้ารหัสต้องมีอย่างน้อย 6 ตัวอักษร
password_encryption_method
password_encryption_method ใช้สำหรับเข้ารหัสรหัสผ่านของผู้ใช้ ค่านี้จะถูกกำหนดเมื่อผู้ใช้ลงทะเบียนด้วยชื่อผู้ใช้และรหัสผ่าน อาจเป็น null ได้
Logto ใช้ Argon2 เวอร์ชัน node-argon2 เป็นวิธีเข้ารหัสโดยค่าเริ่มต้น ดูรายละเอียดเพิ่มเติมได้ใน reference
ตัวอย่าง password_encrypted และ password_encryption_method ของผู้ใช้ที่มีรหัสผ่าน 123456:
{
"password_encryption_method": "Argon2i",
"password_encrypted": "$argon2i$v=19$m=4096,t=10,p=1$aZzrqpSX45DOo+9uEW6XVw$O4MdirF0mtuWWWz68eyNAt2u1FzzV3m3g00oIxmEr0U"
}
is_suspended
is_suspended เป็นค่า boolean ที่ระบุว่าผู้ใช้ถูกระงับหรือไม่ สามารถจัดการค่าได้โดยเรียก Logto Management API หรือใช้ Logto Console
เมื่อผู้ใช้ถูกระงับ โทเค็นรีเฟรชที่ได้รับล่วงหน้าจะถูกเพิกถอนทันที และผู้ใช้จะไม่สามารถยืนยันตัวตนกับ Logto ได้อีก
mfa_verification_factors
mfa_verification_factors เป็น array ที่แสดงรายการวิธี การยืนยันตัวตนหลายปัจจัย (MFA) ที่เชื่อมโยงกับบัญชีผู้ใช้ ค่าที่เป็นไปได้ ได้แก่ Totp (OTP จากแอป Authenticator), WebAuthn (Passkey), และ BackupCode
mfaVerificationFactors: ("Totp" | "WebAuthn" | "BackupCode")[];
ข้อมูลระบุตัวตนทางโซเชียล
identities เก็บข้อมูลผู้ใช้ที่ได้รับจาก การลงชื่อเข้าใช้ด้วยโซเชียล (เช่น ลงชื่อเข้าใช้ด้วย ตัวเชื่อมต่อโซเชียล) identities ของผู้ใช้แต่ละคนจะถูกเก็บใน JSON object แยกกัน
ข้อมูลผู้ใช้จะแตกต่างกันไปตามผู้ให้บริการข้อมูลระบุตัวตนทางโซเชียล (เช่น แพลตฟอร์มโซเชียลเน็ตเวิร์ก) โดยปกติจะประกอบด้วย:
- target ของผู้ให้บริการ เช่น "facebook" หรือ "google"
- รหัสเฉพาะของผู้ใช้สำหรับผู้ให้บริการนี้
- ชื่อของผู้ใช้
- อีเมลที่ได้รับการยืนยันของผู้ใช้
- รูปโปรไฟล์ของผู้ใช้
บัญชีผู้ใช้อาจเชื่อมโยงกับผู้ให้บริการข้อมูลระบุตัวตนทางโซเชียลหลายรายผ่านการลงชื่อเข้าใช้โซเชียล ข้อมูลผู้ใช้ที่ได้จากแต่ละผู้ให้บริการจะถูกเก็บใน object identities
ตัวอย่าง identities ของผู้ใช้ที่ลงชื่อเข้าใช้ทั้ง Google และ Facebook:
{
"facebook": {
"userId": "5110888888888888",
"details": {
"id": "5110888888888888",
"name": "John Doe",
"email": "johndoe@logto.io",
"avatar": "https://example.com/avatar.png"
}
},
"google": {
"userId": "111000000000000000000",
"details": {
"id": "111000000000000000000",
"name": "John Doe",
"email": "johndoe@gmail.com",
"avatar": "https://example.com/avatar.png"
}
}
}
ข้อมูลระบุตัวตน SSO
sso_identities เก็บข้อมูลผู้ใช้ที่ได้รับจาก Enterprise SSO (เช่น Single Sign-On login ด้วย ตัวเชื่อมต่อองค์กร) ssoIdentities ของผู้ใช้แต่ละคนจะถูกเก็บใน JSON object แยกกัน
ข้อมูลที่ซิงก์จากผู้ให้บริการ SSO ขึ้นอยู่กับขอบเขต (scopes) ที่ตั้งค่าไว้ในตัวเชื่อมต่อองค์กร ตัวอย่าง type definition ของ TypeScript:
type SSOIdentity = {
issuer: string;
identityId: string;
detail: JsonObject; // ดู https://github.com/withtyped/withtyped/blob/master/packages/server/src/types.ts#L12
};
ข้อมูลที่กำหนดเอง
custom_data ใช้เก็บข้อมูลผู้ใช้เพิ่มเติมที่ไม่ได้อยู่ในคุณสมบัติผู้ใช้ที่กำหนดไว้ล่วงหน้า
คุณสามารถใช้ custom_data เพื่อทำสิ่งต่อไปนี้:
- บันทึกว่าผู้ใช้ได้ดำเนินการบางอย่างแล้วหรือไม่ เช่น เคยเห็นหน้าต้อนรับแล้ว
- เก็บข้อมูลเฉพาะแอปในโปรไฟล์ผู้ใช้ เช่น ภาษาที่ผู้ใช้ชื่นชอบและโหมดการแสดงผลต่อแอป
- เก็บข้อมูลอื่น ๆ ที่เกี่ยวข้องกับผู้ใช้อย่างอิสระ
ตัวอย่าง custom_data ของผู้ใช้ admin ใน Logto:
{
"adminConsolePreferences": {
"language": "en",
"appearanceMode": "system",
"experienceNoticeConfirmed": true
},
"customDataFoo": {
"foo": "foo"
},
"customDataBar": {
"bar": "bar"
}
}
custom_data ของผู้ใช้แต่ละคนจะถูกเก็บใน JSON object แยกกัน
ห้าม ใส่ข้อมูลสำคัญใน custom_data
ข้อมูลที่กำหนดเองสามารถเข้าถึงได้ผ่าน Custom JWT token claims หลังจากผู้ใช้ลงชื่อเข้าใช้ และ JWT token จะถูกเข้ารหัสแบบ base64 (ไม่ใช่การเข้ารหัสลับ) และถูกส่งผ่านเครือข่ายบ่อยครั้ง ทำให้ข้อมูลสำคัญถูกเปิดเผยได้ง่าย
คุณอาจดึงโปรไฟล์ผู้ใช้ที่มี custom_data โดยใช้ Management API และส่งไปยังแอป frontend หรือบริการ backend ภายนอก ดังนั้นการใส่ข้อมูลสำคัญใน custom_data อาจทำให้ข้อมูลรั่วไหล
หากคุณยังต้องการใส่ข้อมูลสำคัญใน custom_data ขอแนะนำให้เข้ารหัสก่อน และให้เข้ารหัส/ถอดรหัสในระบบที่เชื่อถือได้ เช่น backend ของคุณ และหลีกเลี่ยงการทำใน frontend เพื่อลดความเสียหายหาก custom_data ของผู้ใช้รั่วไหลโดยไม่ตั้งใจ
วิธีเก็บและอัปเดตข้อมูล custom data ของผู้ใช้
- ใช้ฟีเจอร์ Collect user profile เพื่อเก็บข้อมูล custom ระหว่างการสมัครสมาชิก
- ใช้ Account API เพื่อพัฒนาโปรไฟล์หรือการตั้งค่าบัญชีของผู้ใช้
- ใช้
GET /api/my-accountเพื่อดึงข้อมูลผู้ใช้ทั้งหมด - ใช้
PATCH /api/my-accountเพื่ออัปเดต custom_data ของผู้ใช้
- ใช้
- ใช้ Management API สำหรับการจัดการผู้ใช้หรือ flow ขั้นสูง:
- ใช้
GET /api/users/{userId}เพื่อดึงข้อมูลผู้ใช้ทั้งหมด - ใช้
PATCH /api/users/{userId}/custom-dataเพื่ออัปเดต custom_data ของผู้ใช้
- ใช้
- ทีมสนับสนุนของคุณสามารถอัปเดต custom_data ของผู้ใช้ได้โดยตรงใน Console > User management ดูเพิ่มเติมเกี่ยวกับ การดูและอัปเดตโปรไฟล์ผู้ใช้
โปรดอัปเดตอย่างระมัดระวัง การอัปเดต custom_data ของผู้ใช้จะเขียนทับเนื้อหาเดิมทั้งหมดใน storage
ตัวอย่าง หาก input ที่ใช้เรียก API อัปเดต custom_data เป็นดังนี้ (สมมติว่า custom_data เดิมเป็นตัวอย่างก่อนหน้า):
{
"customDataBaz": {
"baz": "baz"
}
}
ค่าของ custom_data ใหม่หลังอัปเดตจะเป็น:
{
"customDataBaz": {
"baz": "baz"
}
}
กล่าวคือ ค่าฟิลด์ที่อัปเดตจะไม่เกี่ยวข้องกับค่าก่อนหน้าเลย
อ้างอิง property
คอลัมน์ในตารางผู้ใช้ของฐานข้อมูลต่อไปนี้ (ยกเว้น password_encrypted และ password_encryption_method) จะแสดงในโปรไฟล์ผู้ใช้ ซึ่งหมายความว่าคุณสามารถค้นหาด้วย Management API ได้
| Name | Type | Description | Unique | Required |
|---|---|---|---|---|
| id | string | รหัสเฉพาะของผู้ใช้ | ✅ | ✅ |
| username | string | ชื่อผู้ใช้สำหรับลงชื่อเข้าใช้ | ✅ | ❌ |
| primary_email | string | อีเมลหลัก | ✅ | ❌ |
| primary_phone | string | หมายเลขโทรศัพท์หลัก | ✅ | ❌ |
| name | string | ชื่อเต็ม | ❌ | ❌ |
| avatar | string | URL ของรูปโปรไฟล์ผู้ใช้ | ❌ | ❌ |
| profile | object | โปรไฟล์ผู้ใช้ | ❌ | ✅ |
| identities | object | ข้อมูลผู้ใช้จากการลงชื่อเข้าใช้โซเชียล | ❌ | ✅ |
| custom_data | object | ข้อมูลเพิ่มเติมใน property ที่กำหนดเอง | ❌ | ✅ |
| application_id | string | รหัสแอปที่ผู้ใช้ลงทะเบียนครั้งแรก | ❌ | ✅ |
| last_sign_in_at | date time | เวลาที่ผู้ใช้ลงชื่อเข้าใช้ล่าสุด | ❌ | ✅ |
| password_encrypted | string | รหัสผ่านที่เข้ารหัส | ❌ | ❌ |
| password_encryption_method | string | วิธีเข้ารหัสรหัสผ่าน | ❌ | ❌ |
| is_suspended | bool | สถานะระงับผู้ใช้ | ❌ | ✅ |
| mfa_verifications | object[] | ปัจจัยการยืนยันตัวตนหลายปัจจัย (MFA) | ❌ | ✅ |
- Unique: รับประกัน ความไม่ซ้ำกัน ของค่าที่ป้อนใน property ของตารางฐานข้อมูล
- Required: รับประกันว่าค่าที่ป้อนใน property ของตารางฐานข้อมูลจะไม่เป็น
null