Självstudie: Anropa flera API:er i iOS-appen med inbyggd autentisering
I den här självstudien får du lära dig hur du skaffar en åtkomsttoken och anropar ett API i din iOS-mobilapp. Med Microsoft Authentication Library (MSAL) intern autentiserings-SDK för iOS kan du hämta flera åtkomsttoken med enkel inloggning. Med den här funktionen kan du hämta en eller flera åtkomsttoken utan att kräva att en användare autentiserar igen.
I den här självstudien lär du dig att:
- Hämta en eller flera åtkomsttoken.
- Anropa ett API
Förutsättningar
- Slutför stegen i Självstudie: Lägg till inloggning och utloggning i iOS-appen med inbyggd autentisering. Den här självstudien visar hur du loggar in användare i din iOS-app med inbyggd autentisering.
- Slutför stegen i Logga in användare och anropa ett API i iOS-exempelmobilappen med inbyggd autentisering
Hämta en eller flera åtkomsttoken
MSAL native authentication SDK kan lagra flera åtkomsttoken. När du har loggat in kan du hämta en åtkomsttoken med hjälp getAccessToken(scope:)
av funktionen och ange omfången för den nya åtkomsttoken som du vill bevilja.
Deklarera och ange värden för en uppsättning API-omfång med hjälp av följande kodfragment:
let protectedAPIUrl1: String? = nil let protectedAPIUrl2: String? = nil let protectedAPIScopes1: [String] = [] let protectedAPIScopes2: [String] = [] var accessTokenAPI1: String? var accessTokenAPI2: String?
protectedAPIUrl1
Initiera med URL:en för ditt första webb-API.protectedAPIUrl2
Initiera med URL:en för ditt andra webb-API.- Definiera
protectedAPIScopes1
med omfång för ditt första API, till exempel["api://<Resource_App_ID>/ToDoList.Read", "api://<Resource_App_ID>/ToDoList.ReadWrite"]
. - Definiera
protectedAPIScopes2
med omfång för ditt andra API, ungefär somprotectedAPIScopes1
. - Deklarera de valfria strängvariablerna
accessTokenAPI1
ochaccessTokenAPI2
.
Loggar in användaren med hjälp av följande kodfragment:
@IBAction func signInPressed(_: Any) { guard let email = emailTextField.text, let password = passwordTextField.text else { resultTextView.text = "Email or password not set" return } print("Signing in with email \(email) and password") showResultText("Signing in...") nativeAuth.signIn(username: email, password: password, delegate: self) }
Metoden
signInPressed
hanterar inloggningsknappen. Den kontrollerar om e-post- och lösenordsfälten är ifyllda. Om någon av dem är tom visas "E-post eller lösenord har inte angetts". Om båda fälten är ifyllda loggar den e-postmeddelandet, visar "Logga in..." och initierar inloggningensignIn
med hjälp av metoden frånnativeAuth
med det angivna e-postmeddelandet och lösenordet. SDK:n hämtar en token som är giltig för OIDC-standardomfången (openid, offline_access, profil) eftersom inga omfång har angetts.Hämta en eller flera åtkomsttoken med hjälp av följande kodfragment:
@IBAction func protectedApi1Pressed(_: Any) { guard let url = protectedAPIUrl1, !protectedAPIScopes1.isEmpty else { showResultText("API 1 not configured.") return } if let accessToken = accessTokenAPI1 { accessProtectedAPI(apiUrl: url, accessToken: accessToken) } else { accountResult?.getAccessToken(scopes: protectedAPIScopes1, delegate: self) let message = "Retrieving access token to use with API 1..." showResultText(message) print(message) } } @IBAction func protectedApi2Pressed(_: Any) { guard let url = protectedAPIUrl2, !protectedAPIScopes2.isEmpty else { showResultText("API 2 not configured.") return } if let accessToken = accessTokenAPI2 { accessProtectedAPI(apiUrl: url, accessToken: accessToken) } else { accountResult?.getAccessToken(scopes: protectedAPIScopes2, delegate: self) let message = "Retrieving access token to use with API 2..." showResultText(message) print(message) } }
Metoderna
protectedApi1Pressed
ochprotectedApi2Pressed
hanterar processen för att hämta åtkomsttoken för två distinkta uppsättningar med omfång. De ser först till att varje API:s URL och omfång är korrekt konfigurerade. Om en åtkomsttoken för API:et redan är tillgänglig kommer den direkt åt API:et. Annars begär den en åtkomsttoken och informerar användaren om den pågående tokenhämtningsprocessen.Om du vill tilldela en åtkomsttoken till
protectedAPIScopes1
ochprotectedAPIScopes2
använder du följande kodfragment:func onAccessTokenRetrieveCompleted(result: MSALNativeAuthTokenResult) { print("Access Token: \(result.accessToken)") if protectedAPIScopes1.allSatisfy(result.scopes.contains), let url = protectedAPIUrl1 { accessTokenAPI1 = result.accessToken accessProtectedAPI(apiUrl: url, accessToken: result.accessToken) } if protectedAPIScopes2.allSatisfy(result.scopes.contains(_:)), let url = protectedAPIUrl2 { accessTokenAPI2 = result.accessToken accessProtectedAPI(apiUrl: url, accessToken: result.accessToken) } showResultText("Signed in." + "\n\n" + "Scopes:\n\(result.scopes)" + "\n\n" + "Access Token:\n\(result.accessToken)") updateUI() } func onAccessTokenRetrieveError(error: MSAL.RetrieveAccessTokenError) { showResultText("Error retrieving access token: \(error.errorDescription ?? "No error description")") }
Metoden
onAccessTokenRetrieveCompleted
skriver ut åtkomsttoken till konsolen. Den kontrollerar sedan omprotectedAPIScopes1
ingår i resultatets omfång och omprotectedAPIUrl1
det är tillgängligt. I så fall angesaccessTokenAPI1
och anropasaccessProtectedAPI
det med URL:en och token. Den utför en liknande kontroll förprotectedAPIScopes2
ochprotectedAPIUrl2
, uppdateraraccessTokenAPI2
och gör API-anropet om villkoren uppfylls. Slutligen visar metoden ett meddelande med inloggningsstatus, omfång och åtkomsttoken och uppdaterar användargränssnittet.Metoden
onAccessTokenRetrieveError
visar ett felmeddelande med beskrivningen av hämtningsfelet för åtkomsttoken eller ett standardmeddelande om ingen beskrivning anges.
Anropa ett API
Använd följande kodfragment för att anropa ett API:
func accessProtectedAPI(apiUrl: String, accessToken: String) {
guard let url = URL(string: apiUrl) else {
let errorMessage = "Invalid API url"
print(errorMessage)
DispatchQueue.main.async {
self.showResultText(errorMessage)
}
return
}
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print("Error found when accessing API: \(error.localizedDescription)")
DispatchQueue.main.async {
self.showResultText(error.localizedDescription)
}
return
}
guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode)
else {
DispatchQueue.main.async {
self.showResultText("Unsuccessful response found when accessing the API")
}
return
}
guard let data = data, let result = try? JSONSerialization.jsonObject(with: data, options: []) else {
DispatchQueue.main.async {
self.showResultText("Couldn't deserialize result JSON")
}
return
}
DispatchQueue.main.async {
self.showResultText("""
Accessed API successfully using access token.
HTTP response code: \(httpResponse.statusCode)
HTTP response body: \(result)
""")
}
}
task.resume()
}
Metoden accessProtectedAPI
skickar en GET-begäran till den angivna API-slutpunkten med hjälp av den angivna åtkomsttoken. Den konfigurerar begäran med token i auktoriseringshuvudet. När det får ett lyckat svar (HTTP-statuskod 200-299) deserialiserar det JSON-data och uppdaterar användargränssnittet med HTTP-statuskoden och svarstexten. Om ett fel uppstår under hanteringen av begäran eller svar visas felmeddelandet i användargränssnittet. Den här metoden ger åtkomst till antingen API 1 eller API 2, beroende på vilken URL och åtkomsttoken som tillhandahålls.
Relaterat innehåll
- Utforska api-referens för intern autentisering.
- Anpassa autentiseringsupplevelsens utseende och känsla för den externa klientorganisationen.