Självstudie: Lägga till inloggning och utloggning i iOS/macOS-appen med inbyggd autentisering
Gäller för: arbetskraftshyresgäster
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
- Självstudie: Förbered din iOS/macOS-app för intern autentisering.
- Om du vill logga in med e-post med lösenord, konfigurerar du användarflödet så att det använder e-post med lösenord när du skapar ditt användarflöde för registrering och inloggning.
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:
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.
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 implementeraSignInStartDelegate
-protokollet. Vi vidarebefordrar en instans avMSALNativeAuthSignInParameters
som innehåller den e-postadress som användaren tillhandahåller i formuläret för e-postinlämning och skickarself
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 avMSALNativeAuthSignInParameters
som innehåller den e-postadress som användaren har angett till oss och deras lösenord, tillsammans med ombudsobjektet som överensstämmer medSignInStartDelegate
protokollet. I det här exemplet skickar vi vidareself
.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 anropasonSignInCodeRequired(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å ennewState
parameter av typenSignInCodeRequiredState
, 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 implementeraSignInVerifyCodeDelegate
-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ämtaaccess token
.getAccessToken(parameters:delegate)
accepterar enMSALNativeAuthGetAccessTokenParameters
-instans och en delegatparameter och vi måste implementera de metoder som krävs iCredentialsDelegate
-protokollet.I det vanligaste scenariot får vi ett anrop till
onAccessTokenRetrieveCompleted(result)
som anger att användaren fick enaccess 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)" } }
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ämtaaccess token
.getAccessToken(parameters:delegate)
accepterar enMSALNativeAuthGetAccessTokenParameters
-instans och en delegatparameter och vi måste implementera de metoder som krävs iCredentialsDelegate
-protokollet.I det vanligaste scenariot får vi ett anrop till
onAccessTokenRetrieveCompleted(result)
som anger att användaren fick enaccess 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.
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")" } }
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 avSignInVerifyCodeDelegate
-protokollet visade vi felet när vi hanteradeonSignInVerifyCodeError(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
.
Konfigurera nyckelringsgruppen för projektet enligt beskrivningen här.
Lägg till en ny medlemsvariabel i klassen
ViewController
:var accountResult: MSALNativeAuthUserAccountResult?
.Uppdatera
viewDidLoad
för att hämta ett cachelagrat konto genom att lägga till den här raden närnativeAuth
har initierats:accountResult = nativeAuth.getNativeAuthUserAccount()
.Uppdatera
signInCompleted
-hanteraren för att lagra kontoresultatet:func onSignInCompleted(result: MSALNativeAuthUserAccountResult) { resultTextView.text = "Signed in successfully" accountResult = result }
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.