Udostępnij za pośrednictwem


Połączenie do lokalnych usług internetowych z symulatorów systemu iOS i emulatorów systemu Android

Wiele aplikacji mobilnych korzysta z usług internetowych. W fazie opracowywania często wdraża się lokalnie usługę internetową i korzysta z niej z aplikacji mobilnej działającej w symulatorze systemu iOS lub emulatorze systemu Android. Pozwala to uniknąć konieczności wdrażania usługi internetowej w hostowanym punkcie końcowym i umożliwia proste debugowanie, ponieważ zarówno aplikacja mobilna, jak i usługa internetowa działają lokalnie.

Aplikacje mobilne działające w symulatorze systemu iOS lub emulatorze systemu Android mogą korzystać z usług internetowych ASP.NET Core działających lokalnie i uwidocznionych za pośrednictwem protokołu HTTP w następujący sposób:

  • Aplikacje działające w symulatorze systemu iOS mogą łączyć się z lokalnymi usługami internetowymi HTTP za pośrednictwem adresu IP maszyn lub za pośrednictwem localhost nazwy hosta. Na przykład, biorąc pod uwagę lokalną usługę internetową HTTP, która uwidacznia operację GET za pośrednictwem /api/todoitems/ względnego identyfikatora URI, aplikacja uruchomiona w symulatorze systemu iOS może korzystać z operacji, wysyłając żądanie GET do http://localhost:<port>/api/todoitems/.
  • Aplikacje działające w emulatorze systemu Android mogą łączyć się z lokalnymi usługami internetowymi HTTP za pośrednictwem 10.0.2.2 adresu, który jest aliasem interfejsu sprzężenia zwrotnego hosta (127.0.0.1 na maszynie dewelopera). Na przykład, biorąc pod uwagę lokalną usługę internetową HTTP, która uwidacznia operację GET za pośrednictwem /api/todoitems/ względnego identyfikatora URI, aplikacja uruchomiona w emulatorze systemu Android może korzystać z operacji, wysyłając żądanie GET do http://10.0.2.2:<port>/api/todoitems/.

Jednak dodatkowa praca jest niezbędna, aby aplikacja uruchomiona w symulatorze systemu iOS lub emulatorze systemu Android mogła korzystać z lokalnej usługi internetowej uwidocznionej za pośrednictwem protokołu HTTPS. W tym scenariuszu proces jest następujący:

  1. Utwórz certyfikat programowania z podpisem własnym na maszynie. Aby uzyskać więcej informacji, zobacz Tworzenie certyfikatu programistycznego.
  2. Skonfiguruj projekt tak, aby używał odpowiedniego HttpClient stosu sieciowego dla kompilacji debugowania. Aby uzyskać więcej informacji, zobacz Konfigurowanie projektu.
  3. Określ adres komputera lokalnego. Aby uzyskać więcej informacji, zobacz Określanie adresu komputera lokalnego.
  4. Pomiń sprawdzanie zabezpieczeń certyfikatu programowania lokalnego. Aby uzyskać więcej informacji, zobacz Obejście sprawdzania zabezpieczeń certyfikatu.

Każdy element zostanie omówiony z kolei.

Tworzenie certyfikatu programistycznego

Zainstalowanie zestawu .NET Core SDK powoduje zainstalowanie certyfikatu dewelopera ASP.NET Core HTTPS w magazynie certyfikatów użytkownika lokalnego. Jednak po zainstalowaniu certyfikatu nie jest zaufany. Aby ufać certyfikatowi, wykonaj następujący jednorazowy krok, aby uruchomić narzędzie dotnet dev-certs :

dotnet dev-certs https --trust

Następujące polecenie zapewnia pomoc w narzędziu dev-certs :

dotnet dev-certs https --help

Alternatywnie po uruchomieniu projektu ASP.NET Core 2.1 (lub nowszego), który używa protokołu HTTPS, program Visual Studio wykryje, czy brakuje certyfikatu deweloperskiego i zaoferuje jego zainstalowanie i zaufanie.

Uwaga

Certyfikat dewelopera ASP.NET Core HTTPS jest z podpisem własnym.

Aby uzyskać więcej informacji na temat włączania lokalnego protokołu HTTPS na maszynie, zobacz Włączanie lokalnego protokołu HTTPS.

Konfigurowanie projektu

Aplikacje platformy Xamarin działające w systemach iOS i Android mogą określać, który stos sieciowy jest używany przez HttpClient klasę, z opcjami stosu zarządzanego sieci lub natywnymi stosami sieciowymi. Zarządzany stos zapewnia wysoki poziom zgodności z istniejącym kodem platformy .NET, ale jest ograniczony do protokołu TLS 1.0 i może być wolniejszy i powodować większy rozmiar pliku wykonywalnego. Natywne stosy mogą być szybsze i zapewniają lepsze zabezpieczenia, ale mogą nie zapewniać wszystkich funkcji HttpClient klasy.

iOS

Aplikacje platformy Xamarin działające w systemie iOS mogą używać zarządzanego stosu sieciowego lub stosów natywnych CFNetwork lub NSUrlSession sieciowych. Domyślnie nowe projekty platformy systemu iOS używają stosu NSUrlSession sieciowego do obsługi protokołu TLS 1.2 i używają natywnych interfejsów API w celu uzyskania lepszej wydajności i mniejszego rozmiaru pliku wykonywalnego. Aby uzyskać więcej informacji, zobacz Selektor implementacji protokołu HTTPClient i SSL/TLS dla systemu iOS/macOS.

Android

Aplikacje platformy Xamarin działające w systemie Android mogą używać zarządzanego HttpClient stosu sieciowego lub natywnego AndroidClientHandler stosu sieciowego. Domyślnie nowe projekty platformy Android używają stosu AndroidClientHandler sieciowego, aby obsługiwać protokół TLS 1.2 i używać natywnych interfejsów API w celu uzyskania lepszej wydajności i mniejszego rozmiaru pliku wykonywalnego. Aby uzyskać więcej informacji na temat stosów sieciowych systemu Android, zobacz HttpClient Stack and SSL/TLS Implementation selector for Android (Selektor implementacji protokołu SSL/TLS dla systemu Android).

Określanie adresu komputera lokalnego

Symulator systemu iOS i emulator systemu Android zapewniają dostęp do bezpiecznych usług internetowych uruchomionych na komputerze lokalnym. Jednak adres komputera lokalnego jest inny dla każdego.

iOS

Symulator systemu iOS używa sieci maszyny hosta. W związku z tym aplikacje uruchomione w symulatorze mogą łączyć się z usługami internetowymi uruchomionymi na komputerze lokalnym za pośrednictwem adresu IP maszyn lub za pośrednictwem localhost nazwy hosta. Na przykład, biorąc pod uwagę lokalną bezpieczną usługę internetową, która uwidacznia operację GET za pośrednictwem /api/todoitems/ względnego identyfikatora URI, aplikacja uruchomiona w symulatorze systemu iOS może korzystać z operacji, wysyłając żądanie GET do https://localhost:<port>/api/todoitems/.

Uwaga

W przypadku uruchamiania aplikacji mobilnej w symulatorze systemu iOS z systemu Windows aplikacja jest wyświetlana w zdalnym symulatorze systemu iOS dla systemu Windows. Jednak aplikacja jest uruchomiona na sparowanym komputerze Mac. W związku z tym nie ma dostępu localhost do usługi internetowej uruchomionej w systemie Windows dla aplikacji systemu iOS uruchomionej na komputerze Mac.

Android

Każde wystąpienie emulatora systemu Android jest odizolowane od interfejsów sieciowych maszyny deweloperów i działa za routerem wirtualnym. W związku z tym emulowane urządzenie nie może zobaczyć maszyny dewelopera ani innych wystąpień emulatora w sieci.

Jednak router wirtualny dla każdego emulatora zarządza specjalną przestrzenią sieciową zawierającą wstępnie przydzielone adresy, a 10.0.2.2 adres jest aliasem interfejsu sprzężenia zwrotnego hosta (127.0.0.1 na maszynie dewelopera). W związku z tym, biorąc pod uwagę lokalną bezpieczną usługę internetową, która uwidacznia operację GET za pośrednictwem /api/todoitems/ względnego identyfikatora URI, aplikacja uruchomiona w emulatorze systemu Android może korzystać z operacji, wysyłając żądanie GET do https://10.0.2.2:<port>/api/todoitems/.

Wykrywanie systemu operacyjnego

Klasa DeviceInfo może służyć do wykrywania platformy, na którym działa aplikacja. Odpowiednią nazwę hosta, która umożliwia dostęp do lokalnych bezpiecznych usług internetowych, można ustawić w następujący sposób:

public static string BaseAddress =
    DeviceInfo.Platform == DevicePlatform.Android ? "https://10.0.2.2:5001" : "https://localhost:5001";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";

Aby uzyskać więcej informacji na temat DeviceInfo klasy, zobacz Xamarin.Essentials: Device Information (Xamarin.Essentials: informacje o urządzeniu).

Pomijanie sprawdzania zabezpieczeń certyfikatu

Próba wywołania lokalnej bezpiecznej usługi internetowej z poziomu aplikacji uruchomionej w symulatorze systemu iOS lub emulatorze systemu Android spowoduje HttpRequestException zgłoszenie nawet w przypadku korzystania z zarządzanego stosu sieciowego na każdej platformie. Dzieje się tak, ponieważ lokalny certyfikat dewelopera HTTPS jest z podpisem własnym, a certyfikaty z podpisem własnym nie są zaufane przez system iOS lub Android. W związku z tym należy zignorować błędy SSL, gdy aplikacja korzysta z lokalnej bezpiecznej usługi internetowej. Można to zrobić w przypadku używania zarówno zarządzanych, jak i natywnych stosów sieciowych w systemach iOS i Android, ustawiając ServerCertificateCustomValidationCallback właściwość obiektu na HttpClientHandler wywołanie zwrotne, które ignoruje wynik sprawdzania zabezpieczeń certyfikatu dla lokalnego certyfikatu dewelopera HTTPS:

// This method must be in a class in a platform project, even if
// the HttpClient object is constructed in a shared project.
public HttpClientHandler GetInsecureHandler()
{
    HttpClientHandler handler = new HttpClientHandler();
    handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) =>
    {
        if (cert.Issuer.Equals("CN=localhost"))
            return true;
        return errors == System.Net.Security.SslPolicyErrors.None;
    };
    return handler;
}

W tym przykładzie kodu wynik weryfikacji certyfikatu serwera jest zwracany, gdy certyfikat, który przeszedł walidację, nie jest certyfikatem localhost . W przypadku tego certyfikatu wynik weryfikacji jest ignorowany i true zwracany, wskazując, że certyfikat jest prawidłowy. Wynikowy HttpClientHandler obiekt powinien zostać przekazany jako argument do konstruktora HttpClient dla kompilacji debugowania:

#if DEBUG
    HttpClientHandler insecureHandler = GetInsecureHandler();
    HttpClient client = new HttpClient(insecureHandler);
#else
    HttpClient client = new HttpClient();
#endif

Włączanie ruchu w postaci zwykłego tekstu HTTP

Opcjonalnie możesz skonfigurować projekty dla systemów iOS i Android, aby zezwalać na ruch HTTP w postaci zwykłego tekstu. Jeśli usługa zaplecza jest skonfigurowana tak, aby zezwalała na ruch HTTP, możesz określić protokół HTTP w podstawowych adresach URL, a następnie skonfigurować projekty tak, aby zezwalały na ruch w postaci zwykłego tekstu:

public static string BaseAddress =
    DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:5000";
public static string TodoItemsUrl = $"{BaseAddress}/api/todoitems/";

Rezygnacja z usługi ATS w systemie iOS

Aby włączyć ruch lokalny w postaci zwykłego tekstu w systemie iOS, należy zrezygnować z usługi ATS , dodając następujące informacje do pliku Info.plist :

<key>NSAppTransportSecurity</key>    
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>

Konfiguracja zabezpieczeń sieci systemu Android

Aby włączyć ruch lokalny w postaci zwykłego tekstu w systemie Android, należy utworzyć konfigurację zabezpieczeń sieci, dodając nowy plik XML o nazwie network_security_config.xml w folderze Resources/xml . Plik XML powinien określać następującą konfigurację:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
  <domain-config cleartextTrafficPermitted="true">
    <domain includeSubdomains="true">10.0.2.2</domain>
  </domain-config>
</network-security-config>

Następnie skonfiguruj właściwość networkSecurityConfig w węźle aplikacji w manifeście systemu Android:

<?xml version="1.0" encoding="utf-8"?>
<manifest>
    <application android:networkSecurityConfig="@xml/network_security_config">
        ...
    </application>
</manifest>

Upewnij się, że akcja kompilacji jest ustawiona jako AndroidResource. W przeciwnym razie plik XML nie zostanie znaleziony w czasie kompilacji.