適用対象:
外部テナント (詳細)
このチュートリアルでは、ネイティブ認証を使用して iOS/macOS アプリで、メールのワンタイム パスコードまたはユーザー名 (メールアドレス) とパスワードの組み合わせを使用してユーザーをサインアップし、ユーザー属性を収集する方法について説明します。
- メールのワンタイム パスコードまたはメール アドレスとパスワードの組み合わせを使用してユーザーを登録します。
- サインアップ中にユーザー属性を収集します。
- サインアップ エラーを処理します。
[前提条件]
- チュートリアル: ネイティブ認証用に iOS アプリを準備します。
- サインアップ中にユーザ属性を収集する場合は、「サインアップとサインインのユーザー フローを作成するときにユーザー属性を構成します。
ユーザーをサインアップする
メールのワンタイム パスコードまたはメール アドレスとパスワードの組み合わせを使用してユーザーをサインアップするには、ユーザーからメール アドレスを収集し、メールのワンタイム パスコードを含むメールをユーザーに送信します。 ユーザーは、有効なメールのワンタイム パスコードを入力し、ユーザー名を検証します。
ユーザーをサインアップするには、次の操作を行う必要があります。
「ユーザーインターフェース (UI) を作成して、以下を行う:」
- ユーザーからメール アドレスを収集します。 ユーザーが有効なメール アドレスを入力していることを確認するために、入力に検証を追加します。
- ユーザー名 (メール アドレス) とパスワードでサインアップした場合、パスワードを収集します。
- ユーザーからメールのワンタイム パスコードを収集します。
- 必要に応じて、ユーザー属性を収集します。
- ユーザーがコードを受信しなかった場合にワンタイム パスコードを再送信します。
- サインアップ フローを開始します。
アプリで、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) }メールのワンタイム パスコードを使用してユーザーをサインアップさせるには、ライブラリの
signUp(parameters:delegate)メソッドを使用します。これは、渡されたデリゲート オブジェクトのメソッドのいずれかを呼び出すことによって非同期で応答します。このオブジェクトはSignUpStartDelegateプロトコルを実装している必要があります。 次のコード行は、ユーザーのサインアップ プロセスを開始します。nativeAuth.signUp(parameters: parameters, delegate: self)signUp(parameters:delegate)メソッドでは、ユーザーの電子メール アドレスを含むMSALNativeAuthSignUpParametersインスタンスをデリゲート (SignUpStartDelegateプロトコルを実装するクラス) と共に送信フォームから渡します。メール アドレスとパスワードの組み合わせを使用してユーザーをサインアップさせるには、次のコード スニペットを使用します。
@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パラメータもあります。これにより、次の 2 つの新しいメソッドにアクセスできます。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)の呼び出しを受け取ります。
サインアップ中にユーザー属性を収集する
ユーザーのサインアップにメールのワンタイム パスコードを使用するか、ユーザー名 (メール アドレス) とパスワードの組み合わせを使用するかに関係なく、ユーザーのアカウントが作成される前にユーザー属性を収集できます。
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パラメーターがあります。これにより、次の 2 つの新しいメソッドにアクセスできます。submitCode(code:delegate)resendCode(delegate)
1つ以上のページにわたるユーザー属性
属性を 1 つ以上のページに分散させるには、顧客 ID およびアクセス管理 (CIAM) テナント構成で、さまざまなページにわたって収集する属性を必須として設定する必要があります。
signUp(parameters:delegate) インスタンスに属性を渡さずに MSALNativeAuthSignUpParameters を呼び出します。 次の手順では、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!"
}
}
このデリゲート メソッドには、newState 型の SignUpAttributesRequiredState パラメータがあり、これを使用して新しいメソッドにアクセスできます。
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: 送信された 1 つ以上の属性が入力検証に失敗したことを示します。 このエラーには、attributeNames パラメータが含まれています。これは、入力検証に失敗した開発者によって送信されたすべての属性のリストです。 -
onSignUpAttributesRequired: ユーザー アカウントを作成するには、1 つ以上の属性の送信をサーバーが要求することを示します。 これは、テナント構成で 1 つ以上の属性が必須として設定されている場合に発生します。 この結果には、属性パラメータが含まれています。これは、API に必要なユーザー属性の詳細を示すMSALNativeAuthRequiredAttributeオブジェクトのリストです。
両方のデリゲート メソッドに新しい状態参照が含まれています。
newState パラメーターを使用して、新しい属性で submitAttributes(attributes:delegate) を再度呼び出します。
サインアップ エラーを処理する
サインアップ中、すべてのアクションが成功するわけではありません。 たとえば、ユーザーが既に使用中のメール アドレスでサインアップしようとしたり、無効なコードを送信したりすることがあります。
以前に 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")"
}
}
省略可能: サインアップ フロー後にサインインする
サインアップ フローが正常に完了したら、サインイン フローを開始せずにユーザーをサインインさせることができます。 詳細については、「チュートリアル: iOS アプリでサインアップ後にユーザーをサインインさせる」の記事をご覧ください。