다음을 통해 공유


자습서: iOS 앱에서 셀프 서비스 암호 재설정

이 자습서에서는 관리자 또는 지원 센터의 개입 없이 사용자가 암호를 변경하거나 다시 설정할 수 있는 기능을 제공하는 방법을 보여 줍니다.

이 자습서에서는 다음을 하는 방법을 알아볼 수 있습니다.

  • 셀프 서비스 암호 재설정을 추가합니다.
  • 오류를 처리합니다.

필수 조건

암호 다시 설정

기존 사용자의 암호를 다시 설정하려면 OTP(일회용 암호)를 사용하여 이메일 주소의 유효성을 검사해야 합니다.

  1. 이메일의 유효성을 검사하려면 다음 코드 조각을 사용하여 SDK 인스턴스에서 resetPassword(username:delegate) 메서드를 호출합니다.

    nativeAuth.resetPassword(username: email, delegate: self)
    
  2. ResetPasswordStartDelegate 프로토콜을 클래스의 확장으로 구현하려면 다음 코드 조각을 사용합니다.

    extension ViewController: ResetPasswordStartDelegate {
        func onResetPasswordCodeRequired(
            newState: MSAL.ResetPasswordCodeRequiredState,
            sentTo: String,
            channelTargetType: MSALNativeAuthChannelType,
            codeLength: Int
        ) {
            resultTextView.text = "Verification code sent to \(sentTo)"
        }
    
        func onResetPasswordStartError(error: MSAL.ResetPasswordStartError) {
            resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
        }
    }
    

    resetPassword(username:delegate)를 호출하면 onResetPasswordCodeRequired() 또는 onResetPasswordStartError() 대리자 메서드가 호출됩니다.

    가장 일반적인 시나리오에서는 사용자의 이메일 주소를 확인하기 위해 코드가 전송되었음을 나타내기 위해 onResetPasswordCodeRequired(newState:sentTo:channelTargetType:codeLength)가 호출됩니다. 코드가 전송된 위치 및 코드에 포함된 자릿수에 대한 세부 정보와 함께 이 대리자 메서드에는 ResetPasswordCodeRequiredState 형식의 newState 매개 변수도 있으며 이를 통해 두 가지 새로운 메서드에 액세스할 수 있습니다.

    • submitCode(code:delegate)
    • resendCode(delegate)

    사용자가 제공한 코드를 제출하려면 다음을 사용합니다.

    newState.submitCode(code: userSuppliedCode, delegate: self)
    
  3. 제출된 코드를 확인하려면 먼저 다음 코드 조각을 사용하여 ResetPasswordVerifyCodeDelegate 프로토콜을 클래스 확장으로 구현합니다.

    extension ViewController: ResetPasswordVerifyCodeDelegate {
    
        func onResetPasswordVerifyCodeError(
            error: MSAL.VerifyCodeError,
            newState: MSAL.ResetPasswordCodeRequiredState?
        ) {
            resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
        }
    
        func onPasswordRequired(newState: MSAL.ResetPasswordRequiredState) {
            // use newState instance to submit the new password
        }
    }
    

    가장 일반적인 시나리오에서는 newState 인스턴스를 사용하여 새 암호를 제공할 수 있음을 나타내는 onPasswordRequired(newState)에 대한 호출을 받습니다.

    newState.submitPassword(password: newPassword, delegate: self)
    
  4. ResetPasswordRequiredDelegate 프로토콜을 클래스의 확장으로 구현하려면 다음 코드 조각을 사용합니다.

    extension ViewController: ResetPasswordRequiredDelegate {
    
        func onResetPasswordRequiredError(
            error: MSAL.PasswordRequiredError,
            newState: MSAL.ResetPasswordRequiredState?
        ) {
            resultTextView.text = "Error submitting new password: \(error.errorDescription ?? "no description")"
        }
    
        func onResetPasswordCompleted(newState: SignInAfterResetPasswordState) {
            resultTextView.text = "Password reset completed"
        }
    }
    

    가장 일반적인 시나리오에서는 암호 재설정 흐름이 완료되었음을 나타내는 onResetPasswordCompleted(newState)에 대한 호출을 받습니다.

오류 처리

ResetPasswordStartDelegate 프로토콜의 이전 구현에서는 onResetPasswordStartError(error) 대리자 함수를 처리할 때 오류를 표시했습니다.

다음과 같이 특정 오류 유형을 처리하여 사용자 환경을 향상할 수 있습니다.

func onResetPasswordStartError(error: MSAL.ResetPasswordStartError) {
    if error.isInvalidUsername {
        resultTextView.text = "Invalid username"
    } else if error.isUserNotFound {
        resultTextView.text = "User not found"
    } else if error.isUserDoesNotHavePassword {
        resultTextView.text = "User is not registered with a password"
    } else {
        resultTextView.text = "Error during reset password flow in: \(error.errorDescription ?? "no description")"
    }
}

상태로 오류 처리

일부 오류에는 새 상태에 대한 참조가 포함됩니다. 예를 들어, 사용자가 잘못된 이메일 확인 코드를 입력한 경우 오류 처리기에는 새 확인 코드를 제출하는 데 사용할 수 있는 ResetPasswordCodeRequiredState에 대한 참조가 포함됩니다.

이전 ResetPasswordVerifyCodeDelegate 프로토콜 구현에서는 onResetPasswordError(error:newState) 대리자 함수를 처리할 때 단순히 오류를 표시했습니다.

사용자에게 올바른 코드를 입력하고 다음과 같이 다시 제출하도록 요청하면 사용자 환경을 개선할 수 있습니다.

func onResetPasswordVerifyCodeError(
    error: MSAL.VerifyCodeError,
    newState: MSAL.ResetPasswordCodeRequiredState?
) {
    if error.isInvalidCode {
        // Inform the user that the submitted code was incorrect and ask for a new code to be supplied.
        // Request a new code calling `newState.resendCode(delegate)`
        let userSuppliedCode = retrieveNewCode(newState)
        newState?.submitCode(code: userSuppliedCode, delegate: self)
    } else {
        resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
    }
}

오류 처리기에 새 상태에 대한 참조가 포함되는 또 다른 예는 사용자가 잘못된 암호를 입력하는 경우입니다. 이 경우 오류 처리기에는 새 암호를 제출하는 데 사용할 수 있는 ResetPasswordRequiredState에 대한 참조가 포함됩니다. 예를 들면 다음과 같습니다.

func onResetPasswordRequiredError(
    error: MSAL.PasswordRequiredError,
    newState: MSAL.ResetPasswordRequiredState?
) {
    if error.isInvalidPassword {
        // Inform the user that the submitted password was invalid and ask for a new password to be supplied.
        let newPassword = retrieveNewPassword()
        newState?.submitPassword(password: newPassword, delegate: self)
    } else {
        resultTextView.text = "Error submitting password: \(error.errorDescription ?? "no description")"
    }
}

암호 재설정 후 로그인

SDK는 개발자에게 사용자 이름을 제공하지 않고도 암호를 다시 설정한 후 사용자에 로그인하거나 일회용 암호를 통해 이메일 주소를 확인할 수 있는 기능을 제공합니다.

암호 재설정에 성공한 후 사용자를 로그인하려면 onResetPasswordCompleted(newState) 함수에서 반환된 새 상태 SignInAfterResetPasswordStatesignIn(delegate) 메서드를 사용합니다.

extension ViewController: ResetPasswordRequiredDelegate {

    func onResetPasswordRequiredError(
        error: MSAL.PasswordRequiredError,
        newState: MSAL.ResetPasswordRequiredState?
    ) {
        resultTextView.text = "Error submitting new password: \(error.errorDescription ?? "no description")"
    }

    func onResetPasswordCompleted() {
        resultTextView.text = "Password reset completed"
        newState.signIn(delegate: self)
    }
}

signIn(delegate)는 대리자 매개 변수를 허용하며 SignInAfterResetPasswordDelegate 프로토콜에 필수 메서드를 구현해야 합니다.

가장 일반적인 시나리오에서는 사용자가 로그인했음을 나타내는 onSignInCompleted(result)에 대한 호출을 받습니다. 결과는 access token을 검색하는 데 사용될 수 있습니다.

extension ViewController: SignInAfterSignUpDelegate {
    func onSignInAfterSignUpError(error: SignInAfterSignUpError) {
        resultTextView.text = "Error signing in after password reset"
    }

    func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) {
        // User successfully signed in
        result.getAccessToken(delegate: self)
    }
}

getAccessToken(delegate)은 대리자 매개 변수를 허용하며 CredentialsDelegate 프로토콜에 필수 메서드를 구현해야 합니다.

가장 일반적인 시나리오에서는 사용자가 access token을 가져왔음을 나타내는 onAccessTokenRetrieveCompleted(result)에 대한 호출을 가져옵니다.

extension ViewController: CredentialsDelegate {
    func onAccessTokenRetrieveError(error: MSAL.RetrieveAccessTokenError) {
        resultTextView.text = "Error retrieving access token"
    }

    func onAccessTokenRetrieveCompleted(result: MSALNativeAuthTokenResult) {
        resultTextView.text = "Signed in. Access Token: \(result.accessToken)"
    }
}

다음 단계