Dela via


Självstudie: Lägga till inloggning och utloggning i iOS/macOS-appen med inbyggd autentisering

Gäller för: vit cirkel med en grå X-symbol. arbetskraftshyresgäster grön cirkel med en vit bocksymbol. externa hyresgäster (lära dig mer)

Den här självstudien visar hur du loggar in och loggar ut en användare med engångslösenord för e-post eller användarnamn och lösenord i din iOS/macOS-app med inbyggd autentisering.

I den här handledningen lär du dig att:

  • Logga in en användare med e-postlösenord eller användarnamn (e-post) och lösenord.
  • Logga ut en användare.
  • Hantera inloggningsfel

Förutsättningar

Logga in användare

För att logga in en användare med hjälp av e-postflöde för engångslösenord, samla in användarens e-postadress och skicka ett e-postmeddelande som innehåller ett engångslösenord för att användaren ska kunna verifiera sin e-post. När användaren anger ett giltigt engångslösenord loggar appen in dem.

För att logga in en användare genom flödet e-post med lösenord, samla in användarens e-post och lösenord. Om användarnamnet och lösenordet är giltiga loggar appen in användaren.

För att logga in en användare måste du:

  1. Skapa ett användargränssnitt (UI) för att:

    • Samla in ett e-postmeddelande från användaren. Lägg till validering i dina indata för att se till att användaren anger en giltig e-postadress.
    • Samla in ett lösenord om du loggar in med användarnamn (e-post) och lösenord.
    • Samla in ett engångslösenord för e-post från användaren om du loggar in med engångslösenord för e-post.
    • Lägg till en knapp så att användaren kan skicka engångslösenordet igen om du loggar in med e-postlösenord för engångslösenord.
  2. I användargränssnittet lägger du till en knapp vars select-händelse startar en inloggning enligt följande kodfragment:

        @IBAction func signInPressed(_: Any) {
        guard let email = emailTextField.text else {
            resultTextView.text = "email not set"
            return
        }
    
        let parameters = MSALNativeAuthSignInParameters(username: email)
        nativeAuth.signIn(parameters: parameters, delegate: self)
    }
    

    Om du vill logga in en användare med E-post engångslösenord flöde använder vi följande kodfragment:

    nativeAuth.signIn(parameters: parameters, delegate: self)
    

    Metoden signIn(parameters:delegate), som svarar asynkront genom att anropa någon av metoderna för det skickade ombudsobjektet, måste implementera SignInStartDelegate-protokollet. Vi vidarebefordrar en instans av MSALNativeAuthSignInParameters som innehåller den e-postadress som användaren tillhandahåller i formuläret för e-postinlämning och skickar self som ombud.

    Om du vill logga in en användare med e-post med lösenord flöde använder vi följande kodfragment:

    let parameters = MSALNativeAuthSignInParameters(username: email)
    parameters.password = password
    nativeAuth.signIn(parameters: parameters, delegate: self)
    

    I signIn(parameters:delegate)-metoden skickar du en instans av MSALNativeAuthSignInParameters som innehåller den e-postadress som användaren har angett till oss och deras lösenord, tillsammans med ombudsobjektet som överensstämmer med SignInStartDelegate protokollet. I det här exemplet skickar vi vidare self.

  3. Använd följande kodfragment för att implementera SignInStartDelegate protokoll när du använder E-post engångslösenord flöde:

    extension ViewController: SignInStartDelegate {
        func onSignInStartError(error: MSAL.SignInStartError) {
            resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")"
        }
    
        func onSignInCodeRequired(
            newState: MSAL.SignInCodeRequiredState,
            sentTo: String,
            channelTargetType: MSAL.MSALNativeAuthChannelType,
            codeLength: Int
        ) {
            resultTextView.text = "Verification code sent to \(sentTo)"
        }
    }
    

    signIn(parameters:delegate) resulterar i ett anrop till delegerade metoder. I det vanligaste scenariot anropas onSignInCodeRequired(newState:sentTo:channelTargetType:codeLength) för att indikera att en kod har skickats för att verifiera användarens e-postadress. Tillsammans med viss information om var koden har skickats och hur många siffror den innehåller, har den här delegatmetoden också en newState parameter av typen SignInCodeRequiredState, vilket ger oss åtkomst till följande två nya metoder:

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

    Använd submitCode(code:delegate) för att skicka engångslösenordet som användaren tillhandahåller i engångslösenordsformuläret med hjälp av följande kodfragment:

    newState.submitCode(code: userSuppliedCode, delegate: self)
    

    submitCode(code:delegate) accepterar engångslösenordet och delegatparametern. När du har skickat koden måste du verifiera engångslösenordet genom att implementera SignInVerifyCodeDelegate-protokollet.

    Om du vill implementera SignInVerifyCodeDelegate protokoll som ett tillägg till klassen använder du följande kodfragment:

    extension ViewController: SignInVerifyCodeDelegate {
        func onSignInVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignInCodeRequiredState?) {
            resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
        }
    
        func onSignInCompleted(result: MSALNativeAuthUserAccountResult) {
            resultTextView.text = "Signed in successfully."
            let parameters = MSALNativeAuthGetAccessTokenParameters()
            result.getAccessToken(parameters: parameters, delegate: self)
        }
    }
    

    I det vanligaste scenariot får vi ett anrop till onSignInCompleted(result) som anger att användaren har loggat in. Resultatet kan användas för att hämta access token.

    getAccessToken(parameters:delegate) accepterar en MSALNativeAuthGetAccessTokenParameters-instans och en delegatparameter och vi måste implementera de metoder som krävs i CredentialsDelegate-protokollet.

    I det vanligaste scenariot får vi ett anrop till onAccessTokenRetrieveCompleted(result) som anger att användaren fick en access token.

    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)"
        }
    }
    
    
  4. Om du vill implementera SignInStartDelegate protokoll när du använder e-post med lösenord flöde använder du följande kodfragment:

    extension ViewController: SignInStartDelegate {
        func onSignInStartError(error: MSAL.SignInStartError) {
            resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")"
        }
    
        func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) {
            // User successfully signed in
        }
    }
    

    I det vanligaste scenariot får vi ett anrop till onSignInCompleted(result) som anger att användaren har loggat in. Resultatet kan användas för att hämta access token.

    getAccessToken(parameters:delegate) accepterar en MSALNativeAuthGetAccessTokenParameters-instans och en delegatparameter och vi måste implementera de metoder som krävs i CredentialsDelegate-protokollet.

    I det vanligaste scenariot får vi ett anrop till onAccessTokenRetrieveCompleted(result) som anger att användaren fick en access token.

    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)"
        }
    }
    
    

Hantera inloggningsfel

Under inloggningen lyckas inte alla åtgärder. Användaren kan till exempel försöka logga in med en e-postadress som inte finns eller skicka en ogiltig kod.

  1. Om du vill hantera fel i metoden signIn(parameters:delegate) använder du följande kodfragment:

    func onSignInStartError(error: MSAL.SignInStartError) {
        if error.isUserNotFound || error.isInvalidUsername {
            resultTextView.text = "Invalid username"
        } else {
            resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")"
        }
    }
    
  2. Om du vill hantera fel i submitCode()-metoden använder du följande kodfragment:

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

    Om användaren anger en felaktig e-postverifieringskod innehåller felhanteraren en referens till en SignInCodeRequiredState som kan användas för att skicka en uppdaterad kod. I vår tidigare implementering av SignInVerifyCodeDelegate-protokollet visade vi felet när vi hanterade onSignInVerifyCodeError(error:newState)-delegatfunktionen.

Läs ID-tokenkraven

När appen har hämtat en ID-token kan du hämta anspråken som är associerade med det aktuella kontot. Om du vill göra det använder du följande kodfragment:

func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) {
   let claims = result.account.accountClaims
   let preferredUsername = claims?["preferred_username"] as? String
}

Nyckeln som du använder för att komma åt anspråksvärdet är det namn som du anger när du lägger till användarattributet som ett tokenanspråk.

Lär dig hur du lägger till inbyggda och anpassade attribut som tokenanspråk i artikeln Lägg till användarattribut till tokenanspråk.

Logga ut användare

Om du vill logga ut en användare använder du referensen till MSALNativeAuthUserAccountResult som du fick i onSignInCompleted återkoppling, eller använder getNativeAuthUserAccount() för att hämta ett inloggat konto från cacheminnet och lagrar en referens i medlemsvariabeln accountResult.

  1. Konfigurera nyckelringsgruppen för projektet enligt beskrivningen här.

  2. Lägg till en ny medlemsvariabel i klassen ViewController: var accountResult: MSALNativeAuthUserAccountResult?.

  3. Uppdatera viewDidLoad för att hämta ett cachelagrat konto genom att lägga till den här raden när nativeAuth har initierats: accountResult = nativeAuth.getNativeAuthUserAccount().

  4. Uppdatera signInCompleted-hanteraren för att lagra kontoresultatet:

    func onSignInCompleted(result: MSALNativeAuthUserAccountResult) {
        resultTextView.text = "Signed in successfully"
    
        accountResult = result
    }
    
  5. Lägg till en utloggningsknapp och använd följande kod för att logga ut användare:

    @IBAction func signOutPressed(_: Any) {
        guard let accountResult = accountResult else {
            print("Not currently signed in")
            return
        }
    
        accountResult.signOut()
    
        self.accountResult = nil
    
        resultTextView.text = "Signed out"
    }
    

Du har slutfört alla nödvändiga steg för att logga ut en användare i din app. Skapa och kör ditt program. Om allt är bra bör du kunna välja utloggningsknappen för att logga ut.

Konfigurera anpassad utfärdare av anspråk

Om du vill lägga till anspråk från ett externt system i den token som utfärdas till din app använder du en leverantör av anpassade anspråk. En anpassad anspråksprovider består av ett anpassat autentiseringstillägg som anropar ett externt REST API för att hämta anspråk från externa system.

Följ stegen i Konfigurera en anpassad anspråksprovider för att lägga till anspråk från ett externt system i dina säkerhetstoken.