適用於:
外部租用戶 (深入瞭解)
本教學示範如何透過 iOS/macOS 應用程式的電子郵件、一次性密碼或使用者名稱(電子郵件)和密碼,透過原生認證註冊使用者。 你也會學會在註冊時收集使用者屬性,包括使用者名稱(別名),以及處理錯誤。
在本教學課程中,您會:
- 使用電子郵件一次性密碼或使用者名稱(電子郵件)和密碼註冊使用者。
- 註冊時收集使用者屬性,包括使用者名稱(別名)。
- 處理註冊錯誤。
先決條件
- 完成 教學步驟:準備你的 iOS/macOS 應用程式進行原生認證。
- 如果您要在註冊期間收集使用者屬性,請在 建立註冊和登入使用者流程時設定使用者屬性,。
- 若要在註冊期間收集使用者名稱(別名),請在您租用戶的註冊使用者流程中啟用 Username 內建使用者屬性。
註冊使用者
要使用電子郵件一次性密碼或使用者名稱(電子郵件)和密碼註冊用戶,你先從用戶那裡收集電子郵件,然後發送包含一次性密碼的電子郵件給用戶。 使用者輸入有效的電子郵件一次性密碼來驗證其用戶名稱。
若要註冊使用者,您需要:
建立使用者介面 (UI) 以:
- 從使用者收集電子郵件。 將驗證新增至您的輸入,以確保使用者輸入有效的電子郵件位址。
- 如果您使用使用者名稱(電子郵件)和密碼註冊,請收集密碼。
- 如果你的應用程式支援別名登入,請收集一個用戶名(alias)。
- 從使用者收集電子郵件一次性密碼。
- 如有需要,請收集用戶屬性。
- 如果使用者未收到密碼,請重新傳送一次性密碼。
- 啟動註冊流程。
在您的應用程式中,新增按鈕,其 select 事件會觸發下列代碼段:
@IBAction func signUpPressed(_: Any) { guard let email = emailTextField.text else { resultTextView.text = "Email or password not set" return } let parameters = MSALNativeAuthSignUpParameters(username: email) nativeAuth.signUp(parameters: parameters, delegate: self) }要使用 Email 一次性密碼註冊使用者,請使用函式庫的方法
signUp(parameters:delegate),該方法會非同步呼叫已通過的代理物件中的某個方法,該方法必須實作該SignUpStartDelegate協定。 下列程式代碼行會啟動使用者註冊流程:nativeAuth.signUp(parameters: parameters, delegate: self)在
signUp(parameters:delegate)方法中,傳遞一個MSALNativeAuthSignUpParameters執行個體,其中包含來自送出表單的使用者電子郵件地址,並同時傳入代理物件(即實作SignUpStartDelegate協定的類別)。若要使用 Email 搭配密碼註冊使用者,請使用下列代碼段:
@IBAction func signUpPressed(_: Any) { guard let email = emailTextField.text, let password = passwordTextField.text else { resultTextView.text = "Email or password not set" return } let parameters = MSALNativeAuthSignUpParameters(username: email) parameters.password = password nativeAuth.signUp(parameters: parameters, delegate: self) }函式庫的
signUp(parameters:delegate)方法會透過呼叫傳入的委派物件上的其中一個方法,以非同步方式回應,而該委派物件必須實作SignUpStartDelegate協定。 下列程式代碼行會啟動使用者註冊流程:nativeAuth.signUp(parameters: parameters, delegate: self)在
signUp(parameters:delegate)方法中,傳遞包含使用者電子郵件地址及密碼的MSALNativeAuthSignUpParameters執行個體,以及委派物件(實作SignUpStartDelegate協定的類別)。若要將協定作為
SignUpStartDelegate類別的擴充,請使用:extension ViewController: SignUpStartDelegate { func onSignUpStartError(error: MSAL.SignUpStartError) { resultTextView.text = "Error signing up: \(error.errorDescription ?? "no description")" } func onSignUpCodeRequired( newState: MSAL.SignUpCodeRequiredState, sentTo: String, channelTargetType: MSAL.MSALNativeAuthChannelType, codeLength: Int ) { resultTextView.text = "Verification code sent to \(sentTo)" } }呼叫
signUp(parameters:delegate)將會觸發onSignUpCodeRequired()或onSignUpStartError()的委派方法。 使用onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength)來表示已發送驗證碼以確認使用者的電子郵件信箱。 除了程式碼被傳送到哪裡、包含多少位數的細節外,這個代理方法還有newState一個型別SignUpCodeRequiredState為 的參數,讓你可以使用兩種新方法:submitCode(code:delegate)resendCode(delegate)
要提交使用者提供的程式碼,請使用:
newState.submitCode(code: userSuppliedCode, delegate: self)若要將協定作為
SignUpVerifyCodeDelegate類別的擴充,請使用:extension ViewController: SignUpVerifyCodeDelegate { func onSignUpVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignUpCodeRequiredState?) { resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")" } func onSignUpCompleted(newState: SignInAfterSignUpState) { resultTextView.text = "Signed up successfully!" } }它
submitCode(code:delegate)接受一個委派參數,你必須在SignUpVerifyCodeDelegate協議中實作所需的方法。 在最常見的情境中,你會收到一通電話onSignUpCompleted(newState),表示使用者已註冊且流程完成。
在註冊期間收集用戶屬性
無論您是使用電子郵件一次性密碼或使用者名稱(電子郵件)和密碼註冊使用者,都可以在建立用戶帳戶之前收集用戶屬性。 您可以使用具有 attributes 屬性的 signUp(parameters:delegate) 來呼叫 MSALNativeAuthSignUpParameters 方法。
若要收集使用者屬性,請使用下列代碼段:
let attributes = [ "country": "United States", "city": "Redmond" ] let parameters = MSALNativeAuthSignUpParameters(username: email) parameters.password = password parameters.attributes = attributes nativeAuth.signUp(parameters: parameters, delegate: self)signUp(parameters:delegate)會導致呼叫onSignUpCodeRequired()或onSignUpStartError()委派方法,或者如果在委派中實作,則呼叫onSignUpAttributesInvalid(attributeNames: [String])。若要將該
SignUpStartDelegate協定作為類別的擴充,請使用以下程式碼片段:extension ViewController: SignUpStartDelegate { func onSignUpStartError(error: MSAL.SignUpStartError) { resultTextView.text = "Error signing up: \(error.errorDescription ?? "no description")" } func onSignUpCodeRequired( newState: MSAL.SignUpCodeRequiredState, sentTo: String, channelTargetType: MSAL.MSALNativeAuthChannelType, codeLength: Int ) { resultTextView.text = "Verification code sent to \(sentTo)" } func onSignUpAttributesInvalid(attributeNames: [String]) { resultTextView.text = "Invalid attributes \(attributeNames)" } }如果屬性無效,則會呼叫 方法
onSignUpAttributesInvalid(attributeNames: [String])。 此時,請將無效屬性清單顯示給使用者。 否則,會呼叫onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength),表示已傳送驗證碼來驗證使用者的電子郵件地址。 除了程式碼接收者與碼數等細節外,此代理方法還有newState一個型別SignUpCodeRequiredState參數,允許你使用兩種新方法:submitCode(code:delegate)resendCode(delegate)
跨一或多個頁面的用戶屬性
若要將屬性分散到一個或多個頁面,請將你打算在不同頁面收集的屬性設為客戶身份與存取管理(CIAM)租戶設定中的強制性。
在 MSALNativeAuthSignUpParameters 執行個體中呼叫 signUp(parameters:delegate) 時,不要傳入任何屬性。 下一步是打電話 newState.submitCode(code: userSuppliedCode, delegate: self) 確認使用者的電子郵件。
像之前一樣實作 SignUpVerifyCodeDelegate 該協定作為類別的擴充,但這次除了必要的方法外,還必須實作選用方法 onSignUpAttributesRequired(attributes:newState) :
extension ViewController: SignUpVerifyCodeDelegate {
func onSignUpAttributesRequired(newState: SignUpAttributesRequiredState) {
resultTextView.text = "Attributes required"
}
func onSignUpVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignUpCodeRequiredState?) {
resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
}
func onSignUpCompleted(newState: SignInAfterSignUpState) {
resultTextView.text = "Signed up successfully!"
}
}
此委派方法具有一個類型為 SignUpAttributesRequiredState 的 newState 參數,可讓您存取一個新方法:
submitAttributes(attributes:delegate)
要提交使用者提供的屬性,請使用以下程式碼片段:
let attributes = [
"country": "United States",
"city": "Redmond"
]
newState.submitAttributes(attributes: attributes, delegate: self)
另外,也請以擴充的方式讓你的類別實作 SignUpAttributesRequiredDelegate 協定:
extension ViewController: SignUpAttributesRequiredDelegate {
func onSignUpAttributesRequiredError(error: AttributesRequiredError) {
resultTextView.text = "Error submitting attributes: \(error.errorDescription ?? "no description")"
}
func onSignUpAttributesRequired(attributes: [MSALNativeAuthRequiredAttribute], newState: SignUpAttributesRequiredState) {
resultTextView.text = "Attributes required"
}
func onSignUpAttributesInvalid(attributeNames: [String], newState: SignUpAttributesRequiredState) {
resultTextView.text = "Attributes invalid"
}
func onSignUpCompleted(newState: SignInAfterSignUpState) {
resultTextView.text = "Signed up successfully!"
}
}
當使用者未提供所有必要的屬性,或屬性無效時,會呼叫這些委派方法:
-
onSignUpAttributesInvalid:表示發送的屬性中,有一個或多個未通過輸入驗證。 此錯誤包含 attributeNames 參數,這是開發人員傳送且輸入驗證失敗的所有屬性清單。 -
onSignUpAttributesRequired:表示伺服器需要傳送一或多個屬性,才能建立用戶帳戶。 當租用戶組態中設定一或多個屬性為必要時,就會發生這種情況。 此結果包含屬性參數,這是一份MSALNativeAuthRequiredAttribute物件清單,其中概述 API 所需使用者屬性的詳細數據。
這兩個委派方法都包含新的狀態參考。 用 newState 參數再次呼叫 submitAttributes(attributes:delegate) 新的屬性。
註冊時請收集用戶名(別名)
使用者名稱(別名)是一個特殊的使用者屬性。 就像城市或國家等其他屬性一樣,你會在註冊時收集這項資料。 與這些屬性不同的是,使用者之後可以使用別名登入。 別名(例如「johndoe」)讓使用者以比電子郵件地址更簡短、更友善的方式登入。
用戶名稱(別名)不會取代使用者名稱(電子郵件)。 註冊時,應用程式必須始終收集使用者名稱(電子郵件)作為主要識別碼,並將別名作為電子郵件的屬性。 登入時,使用者可以選擇使用使用者名稱(電子郵件)或使用者名稱(別名)登入。
當您在註冊使用者流程中啟用內建使用者屬性 Username 時,SDK 會透過與其他屬性相同的屬性字典來接受此屬性,並將 flatusername 作為鍵。 你可以直接在通話中 signUp 傳遞使用者名稱(別名),這樣使用者就不需要再經歷屬性所需的步驟。
要收集使用者名稱(別名),請在註冊介面中與電子郵件欄位並列輸入該使用者名稱,然後在註冊呼叫中將別名作為屬性傳遞:
guard let email = emailTextField.text, !email.isEmpty,
let password = passwordTextField.text, !password.isEmpty,
let username = usernameTextField.text, !username.isEmpty else {
showResultText("Please fill in all fields")
return
}
let attributes: [String: Any] = [
"flatusername": username
]
let parameters = MSALNativeAuthSignUpParameters(username: email)
parameters.password = password
parameters.attributes = attributes
nativeAuth.signUp(parameters: parameters, delegate: self)
對於電子郵件一次性密碼流程(無密碼),在不設定密碼的情況下傳遞屬性:
let parameters = MSALNativeAuthSignUpParameters(username: email)
parameters.attributes = attributes
nativeAuth.signUp(parameters: parameters, delegate: self)
在處理使用者名稱(別名)註冊錯誤時,該 error.isUserAlreadyExists 屬性也會涵蓋重複別名,並 error.isInvalidAttributes 顯示一個無效的別名值。
處理註冊錯誤
註冊期間,並非每個動作都成功。 例如,使用者可能會嘗試使用已使用的電子郵件地址註冊,或提交無效的程序代碼。
在早期的協定實作 SignUpStartDelegate 中,錯誤僅在處理 onSignUpStartError(error) 代理函式時顯示。
若要藉由管理特定錯誤類型來增強使用者體驗,請使用下列代碼段:
func onSignUpStartError(error: MSAL.SignUpStartError) {
if error.isUserAlreadyExists {
resultTextView.text = "Unable to sign up: User already exists"
} else if error.isInvalidPassword {
resultTextView.text = "Unable to sign up: The password is invalid"
} else if error.isInvalidUsername {
resultTextView.text = "Unable to sign up: The username is invalid"
} else {
resultTextView.text = "Unexpected error signing up: \(error.errorDescription ?? "no description")"
}
}
可以選擇在註冊流程之後登入。
註冊流程成功後,你可以在不啟動登入流程的情況下登入使用者。 如果使用者是以使用者名稱(alias)註冊,他們可以用電子郵件地址或別名登入。 若要深入瞭解,請參閱 教學課程:在iOS/macOS 應用程式註冊後自動登入使用者一文。