ข้ามไปยังเนื้อหาหลัก

เพิ่มการยืนยันตัวตนให้กับแอป Android (Kotlin/Java) ของคุณ

คู่มือนี้จะแสดงวิธีการเชื่อมต่อ Logto เข้ากับแอป Android ของคุณ

เคล็ดลับ:
  • ตัวอย่างนี้อ้างอิงจาก View system และ View Model แต่แนวคิดเดียวกันนี้ใช้ได้กับ Jetpack Compose
  • ตัวอย่างเขียนด้วย Kotlin แต่แนวคิดเดียวกันนี้ใช้ได้กับ Java
  • มีโปรเจกต์ตัวอย่างทั้ง Kotlin และ Java ให้ดูใน SDK repository ของเรา
  • วิดีโอแนะนำสามารถรับชมได้ที่ YouTube channel ของเรา

ข้อกำหนดเบื้องต้น

  • บัญชี Logto Cloud หรือ Logto แบบโฮสต์เอง
  • แอปพลิเคชัน Logto แบบ native ที่สร้างไว้แล้ว
  • โปรเจกต์แอป Android ที่ใช้ Kotlin

การติดตั้ง

บันทึก:

ระดับ API ขั้นต่ำของ Android ที่รองรับโดย Logto Android SDK คือระดับ 24

Logto Android SDK มีสองเวอร์ชันหลัก:

  • v3: เปิดประสบการณ์การลงชื่อเข้าใช้ใน Chrome Custom Tabs (เบราว์เซอร์ของระบบ) ซึ่งรองรับการลงชื่อเข้าใช้ด้วย passkey และแชร์เซสชันของเบราว์เซอร์ โปรดทราบว่า v3 ได้ยกเลิกการรองรับ WeChat (Native) และ Alipay (Native) connectors; คุณสามารถใช้ WeChat (Web) และ Alipay (Web) แทน ซึ่งทำงานผ่านเบราว์เซอร์ หากคุณต้องพึ่งพาตัวเชื่อมต่อแบบ native ให้ใช้ v2 ต่อไป
  • v2: เปิดประสบการณ์การลงชื่อเข้าใช้ใน WebView ที่ฝังอยู่ในแอป ซึ่งจำเป็นสำหรับตัวเชื่อมต่อโซเชียลแบบ native แต่ไม่รองรับ การลงชื่อเข้าใช้ด้วย passkey (WebView ไม่รองรับ WebAuthn ซึ่งเป็นมาตรฐานพื้นฐานของ passkey)

คู่มือนี้ครอบคลุมทั้งสองเวอร์ชัน เลือกเวอร์ชันของคุณในแท็บด้านล่าง และตัวเลือกจะถูกซิงค์ตลอดทั้งคู่มือนี้

ก่อนติดตั้ง Logto Android SDK ให้แน่ใจว่าได้เพิ่ม mavenCentral() ในการตั้งค่าที่ repository ของโปรเจกต์ Gradle แล้ว:

settings.gradle.kts
dependencyResolutionManagement {
repositories {
mavenCentral()
}
}

เพิ่ม Logto Android SDK ลงใน dependencies ของคุณ:

ใช้เวอร์ชันล่าสุดของ v3:

build.gradle.kts
dependencies {
implementation("io.logto.sdk:android:3.0.0")
}

เนื่องจาก SDK ต้องการเข้าถึงอินเทอร์เน็ต คุณต้องเพิ่ม permission ต่อไปนี้ในไฟล์ AndroidManifest.xml ของคุณ:

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<!-- เพิ่ม permission สำหรับอินเทอร์เน็ต -->
<uses-permission android:name="android.permission.INTERNET" />

<!-- การตั้งค่าอื่น ๆ... -->
</manifest>

การเชื่อมต่อ

เริ่มต้น LogtoClient

สร้างไฟล์ LogtoViewModel.kt และเริ่มต้น LogtoClient ใน view model นี้:

LogtoViewModel.kt
//...with other imports
import io.logto.sdk.android.LogtoClient
import io.logto.sdk.android.type.LogtoConfig

class LogtoViewModel(application: Application) : AndroidViewModel(application) {
// กำหนดค่า LogtoConfig
private val logtoConfig = LogtoConfig(
endpoint = "<your-logto-endpoint>",
appId = "<your-app-id>",
scopes = null,
resources = null,
usingPersistStorage = true,
)

// เริ่มต้น LogtoClient ด้วย config และ application
private val logtoClient = LogtoClient(logtoConfig, application)

companion object {
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
// ดึง Application object จาก extras
val application = checkNotNull(extras[APPLICATION_KEY])
return LogtoViewModel(application) as T
}
}
}
}

จากนั้น สร้าง LogtoViewModel สำหรับ MainActivity.kt ของคุณ:

MainActivity.kt
//...with other imports
class MainActivity : AppCompatActivity() {
// สร้าง logtoViewModel โดยใช้ Factory
private val logtoViewModel: LogtoViewModel by viewModels { LogtoViewModel.Factory }
//...โค้ดอื่น ๆ
}

กำหนดค่า redirect URI

ก่อนที่เราจะลงลึกในรายละเอียด นี่คือภาพรวมประสบการณ์ของผู้ใช้ปลายทาง กระบวนการลงชื่อเข้าใช้สามารถสรุปได้ดังนี้:

  1. แอปของคุณเรียกใช้งานเมธอดลงชื่อเข้าใช้
  2. ผู้ใช้จะถูกเปลี่ยนเส้นทางไปยังหน้าลงชื่อเข้าใช้ของ Logto สำหรับแอปเนทีฟ ระบบจะเปิดเบราว์เซอร์ของระบบ
  3. ผู้ใช้ลงชื่อเข้าใช้และถูกเปลี่ยนเส้นทางกลับไปยังแอปของคุณ (ตามที่กำหนดไว้ใน redirect URI)

เกี่ยวกับการลงชื่อเข้าใช้แบบเปลี่ยนเส้นทาง (redirect-based sign-in)

  1. กระบวนการยืนยันตัวตนนี้เป็นไปตามโปรโตคอล OpenID Connect (OIDC) และ Logto บังคับใช้มาตรการรักษาความปลอดภัยอย่างเข้มงวดเพื่อปกป้องการลงชื่อเข้าใช้ของผู้ใช้
  2. หากคุณมีหลายแอป คุณสามารถใช้ผู้ให้บริการข้อมูลระบุตัวตน (Logto) เดียวกันได้ เมื่อผู้ใช้ลงชื่อเข้าใช้แอปหนึ่งแล้ว Logto จะดำเนินการลงชื่อเข้าใช้โดยอัตโนมัติเมื่อผู้ใช้เข้าถึงแอปอื่น

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับเหตุผลและประโยชน์ของการลงชื่อเข้าใช้แบบเปลี่ยนเส้นทาง โปรดดูที่ อธิบายประสบการณ์การลงชื่อเข้าใช้ของ Logto


ไปที่หน้ารายละเอียดแอปพลิเคชันของ Logto Console เพิ่ม Redirect URI io.logto.android://io.logto.sample/callback แล้วคลิก "บันทึกการเปลี่ยนแปลง" (Save changes)

Redirect URI ใน Logto Console

ใน Android, redirect URI จะมีรูปแบบ: $(LOGTO_REDIRECT_SCHEME)://$(YOUR_APP_PACKAGE)/callback:

  • LOGTO_REDIRECT_SCHEME ควรเป็น custom scheme ในรูปแบบ reverse domain
  • YOUR_APP_PACKAGE คือชื่อ package ของแอปคุณ

สมมติว่าคุณใช้ io.logto.android เป็น custom LOGTO_REDIRECT_SCHEME และ io.logto.sample เป็นชื่อ package ของแอป, Redirect URI ที่ได้จะเป็น io.logto.android://io.logto.sample/callback

ใน v3 ประสบการณ์การลงชื่อเข้าใช้จะเปิดใน Custom Tab (เบราว์เซอร์ของระบบ) และ redirect จะถูกส่งกลับไปยังแอปของคุณผ่าน intent filter ระดับ OS คุณต้องประกาศ scheme ของ redirect URI ด้วย manifest placeholder logtoRedirectScheme ในไฟล์ build ของแอป:

build.gradle.kts
android {
defaultConfig {
manifestPlaceholders["logtoRedirectScheme"] = "io.logto.android"
}
}

นอกจากนี้ v3 จะบังคับใช้รูปแบบ redirect URI ผ่านการจับคู่ intent filter ของ Android ดังนั้น redirect URI ที่ไม่ตรงตามรูปแบบจะไม่ถูกส่งถึงแอปของคุณ:

  • scheme ต้องตรงกับ manifest placeholder logtoRedirectScheme
  • host ต้องเป็น applicationId ของคุณ
  • path ต้องเป็น /callback

ควรใช้ตัวพิมพ์เล็กสำหรับ scheme และ host เนื่องจากการจับคู่ intent filter เป็นแบบ case-sensitive และเบราว์เซอร์จะเปลี่ยน scheme เป็นตัวพิมพ์เล็ก

หากต้องการใช้ Android App Links (redirect URI แบบ https บนโดเมนของคุณเอง) แทน custom scheme:

  1. โฮสต์ไฟล์ Digital Asset Links ที่ https://your.domain/.well-known/assetlinks.json โดยประกาศ application ID และ SHA-256 fingerprint ของ certificate ที่ใช้เซ็นแอป หากเผยแพร่ผ่าน Play App Signing สามารถดู fingerprint ได้ใน Play Console ที่ Setup > App signing ไฟล์นี้ต้องให้บริการด้วย Content-Type: application/json ตอบกลับ HTTP 200 และไม่มี redirect

  2. ประกาศ intent filter สำหรับ App Links บน activity io.logto.sdk.android.auth.logto.LogtoRedirectReceiverActivity ของ SDK ในไฟล์ AndroidManifest.xml ของคุณ หากคุณไม่ใช้ custom scheme เลย ให้ลบ filter เดิมของ SDK ด้วย tools:node="removeAll" และไม่ต้องใช้ manifest placeholder logtoRedirectScheme อีกต่อไป:

    AndroidManifest.xml
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <application>
    <activity android:name="io.logto.sdk.android.auth.logto.LogtoRedirectReceiverActivity">
    <!-- ละบรรทัดนี้ไว้หากต้องการให้ custom-scheme redirect ทำงานร่วมกัน -->
    <intent-filter tools:node="removeAll" />
    <intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https" android:host="your.domain" android:path="/callback" />
    </intent-filter>
    </activity>
    </application>
    </manifest>
  3. เพิ่ม https://your.domain/callback เป็น redirect URI (และถ้าใช้สำหรับ sign-out ให้เพิ่มเป็น post sign-out redirect URI ด้วย) ในหน้า details ของแอปใน Logto Console และส่งค่าไปที่ signIn / signOut

โปรดทราบว่า callback นี้เป็น URL จริงบนโดเมนของคุณ ดังนั้นควรให้บริการ fallback page (เช่น ปุ่ม “กลับสู่แอป”) สำหรับเบราว์เซอร์ที่ไม่เปิด App Links เมื่อ redirect จาก server ปุ่มนี้เพียงแค่ลิงก์ไปยัง URL ปัจจุบัน (เช่น ตั้ง href เป็น window.location.href) เพราะพารามิเตอร์การอนุญาตอยู่ใน query string และการคลิกโดยผู้ใช้จะให้โอกาส URL นี้ถูกส่งต่อไปยังแอปอีกครั้ง บน Android 12+ หากโดเมนไม่ผ่านการยืนยัน แอปจะไม่ถูกเปิดเลย ดังนั้นหาก assetlinks.json ผิดจะไม่มี error แจ้งเตือน สามารถตรวจสอบสถานะการยืนยันได้ด้วย adb shell pm get-app-links <applicationId>

ดำเนินการ sign-in และ sign-out

บันทึก:

ก่อนเรียก logtoClient.signIn โปรดตรวจสอบให้แน่ใจว่าคุณได้กำหนดค่า Redirect URI ใน Admin Console อย่างถูกต้องแล้ว

คุณสามารถใช้ logtoClient.signIn เพื่อให้ผู้ใช้ลงชื่อเข้าใช้ และ logtoClient.signOut เพื่อให้ผู้ใช้ออกจากระบบ

ใน v3, logtoClient.signOut จะทำการออกจากระบบอย่างสมบูรณ์: ล้างข้อมูลรับรองในเครื่อง, เพิกถอนโทเค็นรีเฟรช (refresh token), และสิ้นสุดเซสชัน Logto โดยเปิด endpoint สำหรับจบเซสชันในเบราว์เซอร์ จากนั้นเบราว์เซอร์จะนำทางกลับไปยังแอปของคุณผ่าน post sign-out redirect URI ก่อนใช้งาน ให้ไปที่หน้ารายละเอียดแอปพลิเคชันใน Logto Console เพิ่ม post sign-out redirect URI io.logto.android://io.logto.sample/callback และคลิก "Save changes" โดย post sign-out redirect URI จะใช้รูปแบบเดียวกับ redirect URI และ scheme ต้องตรงกับ manifest placeholder logtoRedirectScheme ด้วย

ตัวอย่างในแอป Android:

LogtoModelView.kt
//...with other imports
class LogtoViewModel(application: Application) : AndroidViewModel(application) {
// ...other codes

// เพิ่ม live data เพื่อสังเกตสถานะการยืนยันตัวตน
private val _authenticated = MutableLiveData(logtoClient.isAuthenticated)
val authenticated: LiveData<Boolean>
get() = _authenticated

fun signIn(context: Activity) {
logtoClient.signIn(context, "io.logto.android://io.logto.sample/callback") { logtoException ->
logtoException?.let { println(it) }
// อัปเดต live data
_authenticated.postValue(logtoClient.isAuthenticated)
}
}

fun signOut(context: Activity) {
logtoClient.signOut(context, "io.logto.android://io.logto.sample/callback") { logtoException ->
logtoException?.let { println(it) }
// อัปเดต live data
_authenticated.postValue(logtoClient.isAuthenticated)
}
}
}

จากนั้นเรียกใช้เมธอด signIn และ signOut ใน activity ของคุณ:

MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
//...other codes

// สมมติว่าคุณมีปุ่ม id "sign_in_button" ใน layout
val signInButton = findViewById<Button>(R.id.sign_in_button)
signInButton.setOnClickListener {
logtoViewModel.signIn(this)
}

// สมมติว่าคุณมีปุ่ม id "sign_out_button" ใน layout
val signOutButton = findViewById<Button>(R.id.sign_out_button)
signOutButton.setOnClickListener {
if (logtoViewModel.authenticated) { // ตรวจสอบว่าผู้ใช้ได้รับการยืนยันตัวตนหรือไม่
logtoViewModel.signOut(this)
}
}

// สังเกตสถานะการยืนยันตัวตนเพื่ออัปเดต UI
logtoViewModel.authenticated.observe(this) { authenticated ->
if (authenticated) {
// ผู้ใช้ได้รับการยืนยันตัวตนแล้ว
signInButton.visibility = View.GONE
signOutButton.visibility = View.VISIBLE
} else {
// ผู้ใช้ยังไม่ได้รับการยืนยันตัวตน
signInButton.visibility = View.VISIBLE
signOutButton.visibility = View.GONE
}
}

}
}
บันทึก:
  • คุณสามารถเรียก logtoClient.signOut(context) โดยไม่ต้องระบุ post sign-out redirect URI ก็ได้ กรณีนี้ไม่ต้องตั้งค่าใน Console: เบราว์เซอร์จะแสดงหน้าลงชื่อออกของ Logto และผู้ใช้จะกลับสู่แอปโดยปิดหน้าดังกล่าวด้วยตนเอง
  • หากไม่มี UI context คุณสามารถเรียก logtoClient.clearCredentials เพื่อล้างข้อมูลรับรองในเครื่องและเพิกถอนโทเค็นรีเฟรช (refresh token) ได้ โปรดทราบว่าวิธีนี้จะยังคงเซสชัน Logto ในเบราว์เซอร์ไว้ ดังนั้นการ signIn ครั้งถัดไปอาจลงชื่อเข้าใช้โดยอัตโนมัติผ่านเซสชันนั้น

จุดตรวจสอบ: ทดสอบแอปพลิเคชันของคุณ

ตอนนี้คุณสามารถทดสอบแอปพลิเคชันของคุณได้แล้ว:

  1. รันแอปพลิเคชันของคุณ คุณจะเห็นปุ่มลงชื่อเข้าใช้
  2. คลิกปุ่มลงชื่อเข้าใช้ SDK จะเริ่มกระบวนการลงชื่อเข้าใช้และเปลี่ยนเส้นทางคุณไปยังหน้าลงชื่อเข้าใช้ของ Logto
  3. หลังจากที่คุณลงชื่อเข้าใช้แล้ว คุณจะถูกเปลี่ยนเส้นทางกลับไปยังแอปพลิเคชันของคุณและเห็นปุ่มลงชื่อออก
  4. คลิกปุ่มลงชื่อออกเพื่อเคลียร์ที่เก็บโทเค็นและออกจากระบบ

รับข้อมูลผู้ใช้

แสดงข้อมูลผู้ใช้

หากต้องการแสดงข้อมูลของผู้ใช้ สามารถใช้เมธอด logtoClient.getIdTokenClaims() ตัวอย่างเช่น สามารถดึงข้อมูลผู้ใช้ใน ViewModel แล้วนำไปแสดงใน activity ของคุณ:

LogtoModelView.kt
class LogtoViewModel(application: Application) : AndroidViewModel(application) {
// ...โค้ดอื่น ๆ

// เพิ่ม live data สำหรับสังเกต id token claims
private val _idTokenClaims = MutableLiveData<IdTokenClaims>()
val idTokenClaims: LiveData<IdTokenClaims>
get() = _idTokenClaims

fun getIdTokenClaims() {
logtoClient.getIdTokenClaims { logtoException, idTokenClaims ->
logtoException?.let { _logtoException.postValue(it) } ?: _idTokenClaims.postValue(idTokenClaims)
}
}
}
MainActivity.kt
//...import อื่น ๆ
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
//...โค้ดอื่น ๆ

// สมมติว่าคุณมี text View ที่ id `user_info_text_view` ใน layout
val userInfoResponseTextView: TextView = findViewById(R.id.user_info_text_view)
logtoViewModel.userInfoResponse.observe(this) { userInfoResponse ->
userInfoResponseTextView.text = if (userInfoResponse !== null) {
val json = Gson().toJson(userInfoResponse, UserInfoResponse::class.java)
JSONObject(json).toString(2)
} else {
""
}
}
}
}

ขอ claims เพิ่มเติม

คุณอาจพบว่าข้อมูลผู้ใช้บางอย่างหายไปในอ็อบเจกต์ที่ส่งคืนจาก logtoClient.getIdTokenClaims() สาเหตุเนื่องจาก OAuth 2.0 และ OpenID Connect (OIDC) ถูกออกแบบมาให้สอดคล้องกับหลักการสิทธิ์น้อยที่สุด (principle of least privilege; PoLP) และ Logto ถูกสร้างขึ้นบนมาตรฐานเหล่านี้

โดยปกติแล้ว จะมีการส่งคืนการอ้างสิทธิ์ (claim) แบบจำกัด หากคุณต้องการข้อมูลเพิ่มเติม คุณสามารถร้องขอขอบเขต (scope) เพิ่มเติมเพื่อเข้าถึงการอ้างสิทธิ์ (claim) ที่มากขึ้นได้

ข้อมูล:

"การอ้างสิทธิ์ (Claim)" คือการยืนยันข้อมูลบางอย่างเกี่ยวกับผู้ถูกอ้างถึง (subject); "ขอบเขต (Scope)" คือกลุ่มของการอ้างสิทธิ์ (claim) ในกรณีนี้ การอ้างสิทธิ์ (claim) คือข้อมูลบางอย่างเกี่ยวกับผู้ใช้

ตัวอย่างที่ไม่เป็นทางการของความสัมพันธ์ระหว่างขอบเขต (scope) กับการอ้างสิทธิ์ (claim) มีดังนี้:

เคล็ดลับ:

การอ้างสิทธิ์ (claim) "sub" หมายถึง "ผู้ถูกอ้างถึง (subject)" ซึ่งคือตัวระบุที่ไม่ซ้ำของผู้ใช้ (เช่น user ID)

Logto SDK จะร้องขอขอบเขต (scope) สามรายการเสมอ ได้แก่ openid, profile และ offline_access

หากต้องการขอ scopes เพิ่มเติม สามารถส่ง scopes ไปที่อ็อบเจกต์ LogtoConfig ตัวอย่างเช่น:

LogtoViewModel.kt
private val logtoConfig = LogtoConfig(
// ...config อื่น ๆ
scopes = listOf("email", "phone"), // หรือ `listOf(UserScope.EMAIL, UserScope.PHONE)`
)

จากนั้นคุณสามารถเข้าถึง claims เพิ่มเติมในค่าที่คืนมาจาก logtoClient.getIdTokenClaims():

logtoClient.getIdTokenClaims { logtoException, idTokenClaims ->
println("IdTokenClaims:$idTokenClaims")
}
// ตอนนี้คุณสามารถเข้าถึง claims เพิ่มเติม เช่น `claims.email`, `claims.phone` เป็นต้น

การอ้างสิทธิ์ (Claims) ที่ต้องใช้การร้องขอผ่านเครือข่าย

เพื่อป้องกันไม่ให้โทเค็น ID (ID token) มีขนาดใหญ่เกินไป การอ้างสิทธิ์บางรายการจำเป็นต้องร้องขอผ่านเครือข่ายเพื่อดึงข้อมูล ตัวอย่างเช่น การอ้างสิทธิ์ custom_data จะไม่ถูกรวมอยู่ในอ็อบเจกต์ผู้ใช้ แม้ว่าจะร้องขอไว้ในขอบเขต (scopes) ก็ตาม หากต้องการเข้าถึงการอ้างสิทธิ์เหล่านี้ คุณสามารถใช้เมธอด logtoClient.fetchUserInfo():

LogtoViewModel.kt
logtoClient.fetchUserInfo {_, userInfoResponse ->
println("UserInfoResponse:$userInfoResponse")
}
// ตอนนี้คุณสามารถเข้าถึง claim `userInfo.custom_data`
เมธอดนี้จะดึงข้อมูลผู้ใช้โดยการร้องขอไปยัง จุดปลาย userinfo หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับขอบเขต (scopes) และการอ้างสิทธิ์ (claims) ที่มีอยู่ ดูที่หัวข้อ ขอบเขตและการอ้างสิทธิ์

Scopes และ claims

Logto ใช้แนวทาง ขอบเขต (Scope) และ การอ้างสิทธิ์ (Claim) ของ OIDC เพื่อกำหนดขอบเขตและการอ้างสิทธิ์สำหรับดึงข้อมูลผู้ใช้จากโทเค็น ID (ID token) และ OIDC จุดปลาย userinfo ทั้ง "ขอบเขต (Scope)" และ "การอ้างสิทธิ์ (Claim)" เป็นคำศัพท์จากข้อกำหนดของ OAuth 2.0 และ OpenID Connect (OIDC)

สำหรับการอ้างสิทธิ์ OIDC มาตรฐาน การรวมอยู่ในโทเค็น ID จะถูกกำหนดอย่างเคร่งครัดโดยขอบเขตที่ร้องขอ การอ้างสิทธิ์เพิ่มเติม (เช่น custom_data และ organizations) สามารถตั้งค่าเพิ่มเติมให้ปรากฏในโทเค็น ID ได้ผ่าน การตั้งค่า Custom ID token

ต่อไปนี้คือรายการขอบเขต (Scopes) ที่รองรับและการอ้างสิทธิ์ (Claims) ที่เกี่ยวข้อง:

ขอบเขต OIDC มาตรฐาน

openid (ค่าเริ่มต้น)

ชื่อการอ้างสิทธิ์ประเภทคำอธิบาย
substringตัวระบุที่ไม่ซ้ำของผู้ใช้

profile (ค่าเริ่มต้น)

ชื่อการอ้างสิทธิ์ประเภทคำอธิบาย
namestringชื่อเต็มของผู้ใช้
usernamestringชื่อผู้ใช้ของผู้ใช้
picturestringURL ของรูปโปรไฟล์ผู้ใช้ปลายทาง (End-User) URL นี้ต้องอ้างถึงไฟล์รูปภาพ (เช่น PNG, JPEG, หรือ GIF) ไม่ใช่หน้าเว็บที่มีรูปภาพ โปรดทราบว่า URL นี้ควรอ้างอิงถึงรูปโปรไฟล์ของผู้ใช้ปลายทางโดยเฉพาะ เหมาะสำหรับแสดงเมื่ออธิบายผู้ใช้ปลายทาง ไม่ใช่รูปภาพใด ๆ ที่ผู้ใช้ถ่ายมาโดยพลการ
created_atnumberเวลาที่สร้างผู้ใช้ปลายทาง เวลานี้แสดงเป็นจำนวนมิลลิวินาทีตั้งแต่ Unix epoch (1970-01-01T00:00:00Z)
updated_atnumberเวลาที่ข้อมูลของผู้ใช้ปลายทางถูกอัปเดตล่าสุด เวลานี้แสดงเป็นจำนวนมิลลิวินาทีตั้งแต่ Unix epoch (1970-01-01T00:00:00Z)

การอ้างสิทธิ์มาตรฐาน อื่น ๆ เช่น family_name, given_name, middle_name, nickname, preferred_username, profile, website, gender, birthdate, zoneinfo, และ locale จะถูกรวมอยู่ในขอบเขต profile ด้วยโดยไม่จำเป็นต้องร้องขอ endpoint userinfo ความแตกต่างเมื่อเทียบกับการอ้างสิทธิ์ข้างต้นคือ การอ้างสิทธิ์เหล่านี้จะถูกส่งกลับเมื่อค่าของมันไม่ว่างเปล่าเท่านั้น ในขณะที่การอ้างสิทธิ์ข้างต้นจะคืนค่า null หากค่าว่างเปล่า

บันทึก:

ต่างจากการอ้างสิทธิ์มาตรฐาน การอ้างสิทธิ์ created_at และ updated_at ใช้หน่วยเป็นมิลลิวินาทีแทนที่จะเป็นวินาที

email

ชื่อการอ้างสิทธิ์ประเภทคำอธิบาย
emailstringอีเมลของผู้ใช้
email_verifiedbooleanอีเมลได้รับการยืนยันแล้วหรือไม่

phone

ชื่อการอ้างสิทธิ์ประเภทคำอธิบาย
phone_numberstringเบอร์โทรศัพท์ของผู้ใช้
phone_number_verifiedbooleanเบอร์โทรศัพท์ได้รับการยืนยันแล้วหรือไม่

address

โปรดดูรายละเอียดของการอ้างสิทธิ์ที่อยู่ได้ที่ OpenID Connect Core 1.0

ข้อมูล:

ขอบเขตที่มีเครื่องหมาย (ค่าเริ่มต้น) จะถูกร้องขอเสมอโดย Logto SDK การอ้างสิทธิ์ภายใต้ขอบเขต OIDC มาตรฐานจะถูกรวมอยู่ในโทเค็น ID เสมอเมื่อมีการร้องขอขอบเขตที่เกี่ยวข้อง — ไม่สามารถปิดได้

ขอบเขตเพิ่มเติม

ขอบเขตต่อไปนี้เป็นขอบเขตที่ Logto ขยายขึ้นและจะคืนค่าการอ้างสิทธิ์ผ่าน userinfo endpoint การอ้างสิทธิ์เหล่านี้ยังสามารถตั้งค่าให้ถูกรวมอยู่ในโทเค็น ID ได้โดยตรงผ่าน Console > Custom JWT ดู Custom ID token สำหรับรายละเอียดเพิ่มเติม

custom_data

ชื่อการอ้างสิทธิ์ประเภทคำอธิบายรวมในโทเค็น ID โดยค่าเริ่มต้น
custom_dataobjectข้อมูลกำหนดเองของผู้ใช้

identities

ชื่อการอ้างสิทธิ์ประเภทคำอธิบายรวมในโทเค็น ID โดยค่าเริ่มต้น
identitiesobjectข้อมูลตัวตนที่เชื่อมโยงของผู้ใช้
sso_identitiesarrayข้อมูล SSO ที่เชื่อมโยงของผู้ใช้

roles

ชื่อการอ้างสิทธิ์ประเภทคำอธิบายรวมในโทเค็น ID โดยค่าเริ่มต้น
rolesstring[]บทบาท (Role) ของผู้ใช้

urn:logto:scope:organizations

ชื่อการอ้างสิทธิ์ประเภทคำอธิบายรวมในโทเค็น ID โดยค่าเริ่มต้น
organizationsstring[]รหัสองค์กรที่ผู้ใช้สังกัด
organization_dataobject[]ข้อมูลองค์กรที่ผู้ใช้สังกัด
บันทึก:

การอ้างสิทธิ์ขององค์กรเหล่านี้สามารถดึงได้ผ่าน userinfo endpoint เมื่อใช้ โทเค็นทึบ (Opaque token) อย่างไรก็ตาม โทเค็นทึบไม่สามารถใช้เป็นโทเค็นองค์กรสำหรับเข้าถึงทรัพยากรเฉพาะองค์กร ดู โทเค็นทึบและองค์กร สำหรับรายละเอียดเพิ่มเติม

urn:logto:scope:organization_roles

ชื่อการอ้างสิทธิ์ประเภทคำอธิบายรวมในโทเค็น ID โดยค่าเริ่มต้น
organization_rolesstring[]บทบาทขององค์กรที่ผู้ใช้สังกัดในรูปแบบ <organization_id>:<role_name>

ทรัพยากร API และองค์กร

เราแนะนำให้อ่าน 🔐 การควบคุมการเข้าถึงตามบทบาท (RBAC) ก่อน เพื่อทำความเข้าใจแนวคิดพื้นฐานของ RBAC ใน Logto และวิธีตั้งค่าทรัพยากร API อย่างถูกต้อง

กำหนดค่า Logto client

เมื่อคุณตั้งค่า ทรัพยากร API (API resources) เรียบร้อยแล้ว คุณสามารถเพิ่มทรัพยากรเหล่านี้ขณะกำหนดค่า Logto ในแอปของคุณได้:

LogtoViewModel.kt
val logtoConfig = LogtoConfig(
//...other configs
resources = listOf("https://shopping.your-app.com/api", "https://store.your-app.com/api"), // เพิ่มทรัพยากร API
)

แต่ละ ทรัพยากร API (API resource) จะมี สิทธิ์ (scopes) ของตัวเอง

ตัวอย่างเช่น ทรัพยากร https://shopping.your-app.com/api มีสิทธิ์ shopping:read และ shopping:write และทรัพยากร https://store.your-app.com/api มีสิทธิ์ store:read และ store:write

หากต้องการร้องขอสิทธิ์เหล่านี้ คุณสามารถเพิ่มขณะกำหนดค่า Logto ในแอปของคุณได้:

LogtoViewModel.kt
val logtoConfig = LogtoConfig(
// ..การตั้งค่าอื่น ๆ
scopes = listOf("shopping:read", "shopping:write", "store:read", "store:write"),
resources = listOf("https://shopping.your-app.com/api", "https://store.your-app.com/api"),
)

คุณอาจสังเกตได้ว่า ขอบเขต (scopes) ถูกกำหนดแยกจาก ทรัพยากร API (API resources) นี่เป็นเพราะ Resource Indicators for OAuth 2.0 ระบุว่า ขอบเขตสุดท้ายสำหรับคำขอจะเป็นผลคูณคาร์ทีเซียนของขอบเขตทั้งหมดในบริการเป้าหมายทั้งหมด

ดังนั้น ในกรณีข้างต้น ขอบเขต (scopes) สามารถทำให้เรียบง่ายขึ้นจากการกำหนดใน Logto โดยทั้งสอง ทรัพยากร API (API resources) สามารถมีขอบเขต read และ write ได้โดยไม่ต้องมีคำนำหน้า จากนั้น ในการตั้งค่า Logto:

LogtoViewModel.kt
val logtoConfig = LogtoConfig(
// ...การตั้งค่าอื่น ๆ
scopes = listOf("read", "write"),
resources = listOf("https://shopping.your-app.com/api", "https://store.your-app.com/api"),
)

สำหรับแต่ละ ทรัพยากร API (API resource) จะร้องขอทั้งขอบเขต read และ write

บันทึก:

คุณสามารถร้องขอขอบเขต (scopes) ที่ไม่ได้กำหนดไว้ใน ทรัพยากร API (API resources) ได้ เช่น คุณสามารถร้องขอขอบเขต email ได้ แม้ว่า ทรัพยากร API (API resources) จะไม่มีขอบเขต email ให้ ขอบเขตที่ไม่มีจะถูกละเว้นอย่างปลอดภัย

หลังจากลงชื่อเข้าใช้สำเร็จ Logto จะออกขอบเขตที่เหมาะสมให้กับ ทรัพยากร API (API resources) ตามบทบาทของผู้ใช้

ดึง access token สำหรับ API resource

เพื่อดึงโทเค็นการเข้าถึง (Access token) สำหรับทรัพยากร API เฉพาะ คุณสามารถใช้เมธอด getAccessToken ได้ดังนี้:

LogtoViewModel.kt
logtoClient.getAccessToken("https://shopping.your-app.com/api") { logtoException, accessToken ->
logtoException?.let { println(it) }
accessToken?.let { println(it) }
}

เมธอดนี้จะส่งคืนโทเค็นการเข้าถึง (JWT access token) ที่สามารถใช้เข้าถึงทรัพยากร API ได้เมื่อผู้ใช้มีสิทธิ์ที่เกี่ยวข้อง หากโทเค็นการเข้าถึงที่แคชไว้หมดอายุแล้ว เมธอดนี้จะพยายามใช้โทเค็นรีเฟรช (Refresh token) เพื่อขอโทเค็นการเข้าถึงใหม่โดยอัตโนมัติ

ดึงโทเค็นองค์กร

หากคุณยังไม่คุ้นเคยกับ องค์กร (Organization) โปรดอ่าน 🏢 องค์กร (หลายผู้เช่า; Multi-tenancy) เพื่อเริ่มต้น

คุณต้องเพิ่ม UserScope.Organizations ขอบเขต (scope) ขณะตั้งค่า Logto client:

LogtoViewModel.kt
val logtoConfig = LogtoConfig(
// ...other configs
scopes = listOf(UserScope.Organizations), // ขอบเขต (scopes) = รายการของ UserScope.Organizations
)

เมื่อผู้ใช้ลงชื่อเข้าใช้แล้ว คุณสามารถดึงโทเค็นองค์กร (organization token) สำหรับผู้ใช้ได้:

LogtoViewModel.kt
// แทนที่พารามิเตอร์ด้วยรหัสองค์กรที่ถูกต้อง
// สามารถดูรหัสองค์กรที่ถูกต้องสำหรับผู้ใช้ได้ในการอ้างสิทธิ์ (claim) โทเค็น ID `organizations`
logtoClient.getOrganizationToken("organization-id") { logtoException, organizationToken ->
logtoException?.let { println(it) }
organizationToken?.let { println(it) }
}

// หรือ
logtoClient.getOrganizationTokenClaims("organization-id") { logtoException, claims ->
logtoException?.let { println(it) }
claims?.let { println(it) }
}

ทรัพยากร API ขององค์กร (Organization API resources)

หากต้องการดึงโทเค็นการเข้าถึง (Access token) สำหรับทรัพยากร API ในองค์กร คุณสามารถใช้เมธอด getAccessToken พร้อมทั้งระบุทั้งทรัพยากร API และรหัสองค์กรเป็นพารามิเตอร์:

LogtoViewModel.kt
logtoClient.getAccessToken(
'https://shopping.your-app.com/api',
organizationId
) { logtoException, accessToken ->
println("AccessToken:$accessToken")
}

อ่านเพิ่มเติม

กระบวนการสำหรับผู้ใช้ปลายทาง: กระบวนการยืนยันตัวตน, กระบวนการบัญชี, และกระบวนการองค์กร ตั้งค่าตัวเชื่อมต่อ การอนุญาต (Authorization)