โครงสร้างข้อมูลผู้ใช้
ผู้ใช้คือเอนทิตีหลักในบริการข้อมูลระบุตัวตน ใน Logto ผู้ใช้จะมีข้อมูลการยืนยันตัวตนพื้นฐานตามโปรโตคอล OpenID Connect พร้อมกับข้อมูลที่กำหนดเอง
โปรไฟล์ผู้ใช้
ผู้ใช้แต่ละคนจะมีโปรไฟล์ที่ประกอบด้วย ข้อมูลผู้ใช้ทั้งหมด
ประกอบด้วยข้อมูลประเภทต่อไปนี้:
- ข้อมูลพื้นฐาน: คือข้อมูลพื้นฐานจากโปรไฟล์ผู้ใช้ เก็บคุณสมบัติอื่น ๆ ของ user ทั้งหมด ยกเว้น
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 ตัวอักษร ประกอบด้วยตัวอักษร ตัวเลข และขีดล่าง (_) เท่านั้น และต้องไม่ขึ้นต้นด้วยตัวเลข โดยค่าเริ่มต้นจะเป็น case-sensitive กฎเหล่านี้สามารถกำหนดเข้มงวดขึ้นต่อ 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 ค่านี้อาจได้มาจากข้อมูลผู้ใช้โซเชียล
คุณสมบัตินี้จะถูกแมปกับ picture claim ในมาตรฐาน 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 หรือ userinfo endpoint response เฉพาะเมื่อค่าของมันไม่ว่าง ในขณะที่ standard claims อื่น ๆ จะคืนค่า null หากค่าว่าง
ข้อยกเว้นคือ preferred_username claim: เมื่อ preferredUsername ใน profile ว่าง จะ 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 identities
sso_identities เก็บข้อมูลผู้ใช้ที่ได้จาก Enterprise SSO (เช่น Single Sign-On login ด้วย ตัวเชื่อมต่อองค์กร) ssoIdentities ของผู้ใช้แต่ละคนจะถูกเก็บใน JSON object แยกกัน
ข้อมูลที่ซิงค์จากผู้ให้บริการ SSO ขึ้นอยู่กับ scopes ที่ตั้งค่าไว้ในตัวเชื่อมต่อองค์กร ตัวอย่าง TypeScript type definition:
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 ของผู้ใช้แอดมินใน Logto:
{
"adminConsolePreferences": {
"language": "en",
"appearanceMode": "system",
"experienceNoticeConfirmed": true
},
"customDataFoo": {
"foo": "foo"
},
"customDataBar": {
"bar": "bar"
}
}
custom_data ของผู้ใช้แต่ละคนจะถูกเก็บใน JSON object แยกกัน หากต้องการค้นหาผู้ใช้ด้วยค่าข้อมูลที่กำหนดเองแบบตรงเป๊ะ ดู ค้นหาด้วย custom data
ห้าม ใส่ข้อมูลสำคัญใน 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 data ระหว่างการสมัครสมาชิก
- ใช้ 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