Samouczek: wywoływanie wielu interfejsów API w aplikacji systemu iOS przy użyciu uwierzytelniania natywnego
Z tego samouczka dowiesz się, jak uzyskać token dostępu i wywołać interfejs API w aplikacji mobilnej systemu iOS. Natywny zestaw SDK uwierzytelniania biblioteki Microsoft Authentication Library (MSAL) dla systemu iOS umożliwia uzyskanie wielu tokenów dostępu przy użyciu logowania jednokrotnego. Ta funkcja umożliwia uzyskanie co najmniej jednego tokenu dostępu bez konieczności ponownego uwierzytelnienia użytkownika.
Z tego samouczka dowiesz się, jak wykonywać następujące czynności:
- Uzyskaj jeden lub wiele tokenów dostępu.
- Wywoływanie interfejsu API
Wymagania wstępne
- Wykonaj kroki opisane w artykule Samouczek: dodawanie logowania i wylogowywanie w aplikacji systemu iOS przy użyciu uwierzytelniania natywnego. W tym samouczku pokazano, jak logować użytkowników w aplikacji systemu iOS przy użyciu uwierzytelniania natywnego.
- Wykonaj kroki opisane w temacie Logowanie użytkowników i wywoływanie interfejsu API w przykładowej aplikacji mobilnej systemu iOS przy użyciu uwierzytelniania natywnego
Uzyskiwanie jednego lub wielu tokenów dostępu
Zestaw SDK uwierzytelniania natywnego biblioteki MSAL może przechowywać wiele tokenów dostępu. Po zalogowaniu można uzyskać token dostępu przy użyciu getAccessToken(scope:)
funkcji i określić zakresy dla nowego tokenu dostępu, który chcesz udzielić.
Zadeklaruj i ustaw wartości dla zestawu zakresów interfejsu API przy użyciu następującego fragmentu kodu:
let protectedAPIUrl1: String? = nil let protectedAPIUrl2: String? = nil let protectedAPIScopes1: [String] = [] let protectedAPIScopes2: [String] = [] var accessTokenAPI1: String? var accessTokenAPI2: String?
- Zainicjuj
protectedAPIUrl1
adres URL pierwszego internetowego interfejsu API. - Zainicjuj
protectedAPIUrl2
adres URL drugiego internetowego interfejsu API. - Zdefiniuj
protectedAPIScopes1
zakresy dla pierwszego interfejsu API, na przykład["api://<Resource_App_ID>/ToDoList.Read", "api://<Resource_App_ID>/ToDoList.ReadWrite"]
. - Zdefiniuj
protectedAPIScopes2
zakresy dla drugiego interfejsu API, podobnie jakprotectedAPIScopes1
. - Zadeklaruj opcjonalne zmienne
accessTokenAPI1
ciągu iaccessTokenAPI2
.
- Zainicjuj
Loguje użytkownika przy użyciu następującego fragmentu kodu:
@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) }
Metoda
signInPressed
obsługuje naciśnięcie przycisku logowania. Sprawdza, czy pola wiadomości e-mail i hasła są wypełnione. Jeśli wartość jest pusta, zostanie wyświetlony komunikat "Adres e-mail lub hasło nie jest ustawione". Jeśli oba pola są wypełnione, rejestruje wiadomość e-mail, wyświetla komunikat "Logowanie..." i inicjuje logowanie przy użyciusignIn
metody znativeAuth
podanej wiadomości e-mail i hasła. Zestaw SDK pobiera token prawidłowy dla domyślnych zakresów OIDC (openid, offline_access, profile), ponieważ nie określono zakresów.Uzyskaj jeden lub wiele tokenów dostępu przy użyciu następującego fragmentu kodu:
@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) } }
Metody
protectedApi1Pressed
iprotectedApi2Pressed
zarządzają procesem uzyskiwania tokenów dostępu dla dwóch odrębnych zestawów zakresów. Najpierw upewniają się, że adres URL i zakresy poszczególnych interfejsów API są prawidłowo skonfigurowane. Jeśli token dostępu dla interfejsu API jest już dostępny, uzyskuje bezpośredni dostęp do interfejsu API. W przeciwnym razie żąda tokenu dostępu i informuje użytkownika o trwającym procesie pobierania tokenu.Aby przypisać token dostępu do
protectedAPIScopes1
elementów iprotectedAPIScopes2
, użyj następującego fragmentu kodu: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")") }
Metoda
onAccessTokenRetrieveCompleted
wyświetla token dostępu do konsoli. Następnie sprawdza, czyprotectedAPIScopes1
są uwzględnione w zakresach wyniku i czyprotectedAPIUrl1
są dostępne. Jeśli tak, ustawiaaccessTokenAPI1
i wywołujeaccessProtectedAPI
adres URL i token. Wykonuje on podobne sprawdzanieprotectedAPIScopes2
parametrów iprotectedAPIUrl2
, aktualizującaccessTokenAPI2
i wykonując wywołanie interfejsu API w przypadku spełnienia warunków. Na koniec metoda wyświetla komunikat ze stanem logowania, zakresami i tokenem dostępu oraz aktualizuje interfejs użytkownika.Metoda
onAccessTokenRetrieveError
wyświetla komunikat o błędzie z opisem błędu pobierania tokenu dostępu lub komunikatem domyślnym, jeśli nie podano opisu.
Wywoływanie interfejsu API
Użyj następujących fragmentów kodu, aby wywołać interfejs 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()
}
Metoda accessProtectedAPI
wysyła żądanie GET do określonego punktu końcowego interfejsu API przy użyciu podanego tokenu dostępu. Konfiguruje żądanie za pomocą tokenu w nagłówku Autoryzacja. Po otrzymaniu pomyślnej odpowiedzi (kod stanu HTTP 200–299) deserializuje dane JSON i aktualizuje interfejs użytkownika przy użyciu kodu stanu HTTP i treści odpowiedzi. Jeśli podczas obsługi żądania lub odpowiedzi wystąpi błąd, zostanie wyświetlony komunikat o błędzie w interfejsie użytkownika. Ta metoda umożliwia dostęp do interfejsu API 1 lub API 2 w zależności od podanego adresu URL i tokenu dostępu.
Powiązana zawartość
- Zapoznaj się z dokumentacją interfejsu API uwierzytelniania natywnego.
- Dostosowywanie wyglądu i działania środowiska uwierzytelniania dla dzierżawy zewnętrznej.