Tworzenie bezpiecznego logowania na Androidzie przy użyciu Google OAuth
Published: 2024-03-11 00:47:45

Ponieważ szacuje się, że w styczniu 2022 r. 4,55 miliarda ludzi [posiadało co najmniej jeden profil w mediach społecznościowych](https://www.statista.com/statistics/278414/number-of-worldwide-social-network-users/), nie jest zaskoczeniem, że większość aplikacji ma jakiś rodzaj logowania społecznościowego jako łatwy sposób, aby ich użytkownicy mogli wejść na pokład. Ma to kluczowe znaczenie dla poprawy komfortu użytkowania. Z perspektywy rozwoju istnieje główna wspólna cecha wszystkich tych dostawców logowania społecznościowego, takich jak Facebook, Twitter i Google. Tym wspólnym elementem układanki jest **OAuth**, a dokładniej **OAuth 2.0**. Ale nie chodzi tylko o korzystanie z OAuth, wymaga to prawidłowego zrozumienia zakresów, identyfikatora klienta OAuth i ekranu zgody OAuth w celu optymalnej implementacji.

Jaka jest różnica między uwierzytelnianiem a autoryzacją?
---------------------------------------------------------

[Uwierzytelnianie](https://www.pubnub.com/learn/glossary/what-is-authentication/) (authn) odnosi się do procesu identyfikacji lub weryfikacji użytkownika, w tym kontekście można to zrobić za pomocą Google OAuth. Z drugiej strony, [autoryzacja](https://www.pubnub.com/learn/glossary/what-is-authorization/) (authz) dotyczy tego, czy uwierzytelniony użytkownik ma _\_uprawnienia potrzebne\__ do uzyskania dostępu do określonego zasobu. W tym miejscu zakresy odgrywają kluczową rolę, ponieważ definiują uprawnienia w OAuth.

Zarówno authn, jak i authz są ze sobą ściśle powiązane i zazwyczaj występują w ramach procesu OAuth 2.0. W przypadku obu części procesu będziemy potrzebować serwera do przechowywania [identyfikatora klienta i tajemnicy klienta](https://www.oauth.com/oauth2-servers/client-registration/client-id-secret/), którymi można zarządzać za pomocą Google Cloud.

Jak Authn i Authz pasują do OAuth
---------------------------------

**OAuth jest ściśle standardem autoryzacji**, a głównym błędnym przekonaniem wśród programistów jest to, że authn (uwierzytelnianie) jest jego częścią. OAuth 2.0 obejmuje również authn, zwłaszcza na platformach społecznościowych, takich jak Google, gdzie procesy są uruchamiane kolejno przy użyciu kombinacji natywnych technologii, Javascript lub Kotlin.

Oto przegląd tego procesu:

![](https://www.pubnub.com/cdn/3prze68gbwl1/asset-17suaysk1qa1jgb/a9cc177f71949ce3ab9e9117b59323be/Oauth-Flow.png)

Jak widać, istnieją dwa podstawowe komponenty. Początkowo musimy mieć wymaganą autoryzację od użytkownika. Dzieje się tak, jeśli użytkownik jest zalogowany, w tym miejscu wiele interfejsów API będzie powiązanych z uwierzytelnianiem OAuth przy użyciu openid. Po otrzymaniu dotacji od organu konta użytkownika możemy rozpocząć komunikację z właścicielem zasobu. Po wysłaniu grantu do serwera autoryzacji otrzymujemy z powrotem token dostępu. Teraz, dzięki tokenowi dostępu, możemy uzyskać dostęp do potrzebnych informacji związanych z użytkownikiem.

Podczas implementacji OAuth 2.0 kluczowe jest skonfigurowanie poprawnych identyfikatorów URI przekierowania i wywołania zwrotnego, ponieważ każdy drobny błąd w tych parametrach może spowodować niepowodzenie procesu authn i authz. Ponadto, w ramach zwiększania bezpieczeństwa i wygody użytkownika, Google udostępnia rozszerzenie chrome dla OAuth 2.0.

Uwierzytelnianie za pomocą Google Sign-in w systemie Android
------------------------------------------------------------

Uwierzytelnianie aplikacji na Androida, w szczególności za pomocą logowania Google, jest powszechnym środkiem bezpieczeństwa. Ale nie chodzi tylko o dodanie Google do aplikacji na Androida, zaczyna się od zrozumienia OAuth, a następnie zagłębienia się w SDK i Google API.

Aby rozpocząć korzystanie z Google Sign-in, użyjemy [Functions](https://www.pubnub.com/docs/functions/overview), funkcji PubNub, która służy jako nasz serwer. Funkcje te sprawią, że implementacja powiadomień w procesie OAuth będzie prostsza. Fragmenty kodu dla procesu OAuth można również znaleźć na GitHub.

Ponadto upewnij się, że masz skonfigurowane [konto Google API](https://developers.google.com/identity/sign-in/android/start-integrating) z poprawną nazwą pakietu oraz skonfigurowany identyfikator klienta OAuth i ekran zgody OAuth.

Następnie dodamy Google do naszej aplikacji na Androida, abyśmy mogli rozpocząć proces logowania. Najpierw upewnij się, że masz linię `repozytoria { google() }` w pliku Gradle na poziomie projektu. Spowoduje to otwarcie aplikacji w celu wykorzystania Google SDK.

Następnie przejdź do pliku Gradle na poziomie aplikacji i zaktualizuj zależność autoryzacji usług Google Play. Od stycznia 2022 roku najnowszą wersją jest `com.google.android.gms:play-services-auth:19.2.0`.

```js
    implementation 'com.google.android.gms:play-services-auth:19.2.0'
```

Teraz, mimo że mamy zaktualizowaną zależność dodaną do naszego projektu, nie będziemy jeszcze w stanie przejść przez proces logowania. Musisz edytować plik manifestu Androida, aby dodać uprawnienia internetowe dotyczące Firebase:

```js
    <uses-permission android:name="android.permission.INTERNET" />
```

### Dodawanie przycisku logowania Google

Ten etap jest dość prosty. Dodaj komponent logowania do pliku `activity_main.xml`. Przycisk logowania jest stylizowany przez Google, ale na wszelki wypadek zapoznaj się z [wytycznymi Google dotyczącymi marki](https://about.google/brand-resource-center/). Pamiętaj, że dobre wrażenia użytkownika są kluczowe w aplikacjach komputerowych, a to obejmuje stylizacje i identyfikatory używane na przycisku logowania.

```js
    <com.google.android.gms.common.SignInButton
                android:id="@+id/sign_in_button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                app:layout_constraintBottom_toBottomOf="parent" android:layout_marginTop="8dp"
                app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
                android:layout_marginStart="8dp" app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
                app:layout_constraintVertical_bias="0.665"
    />
```

W aplikacjach na Androida uwierzytelnianie za pomocą logowania Google jest powszechnym środkiem bezpieczeństwa. Tutaj możesz zobaczyć przykład działania tego procesu w `MainActivity`. Ten fragment służy jako przewodnik do implementacji logowania Google przy użyciu Kotlin.

```js
class MainActivity : AppCompatActivity() {
    private val RC_SIGN_IN = 9001
    private var mGoogleSignInClient: GoogleSignInClient? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
            .requestIdToken(getString(R.string.server_client_id))
            .requestEmail()
            .build()
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
    }
    public override fun onStart() {
        super.onStart()
        val mGmailSignIn = findViewById<SignInButton>(R.id.sign_in_button)
        val account = GoogleSignIn.getLastSignedInAccount(this)
        Log.w("Sign In: ", account.toString())
        mGmailSignIn.setOnClickListener {
                signIn()
        }
    }
    public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == RC_SIGN_IN) {
            val task = GoogleSignIn.getSignedInAccountFromIntent(data)
            handleSignInResult(task)
        }
    }
    private fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) {
        Log.w("Sign In: ", completedTask.toString())
        try {
            val account = completedTask.getResult(ApiException::class.java)
            val idToken = account!!.idToken
            Log.w("Sign In: ", idToken.toString())
            authCheck(idToken.toString())
        } catch (e: ApiException) {
            Log.w("Sign In: ", "signInResult:failed code=" + e.statusCode)
        }
    }
    private fun signIn() {
        val signInIntent = mGoogleSignInClient!!.signInIntent
        startActivityForResult(signInIntent, RC_SIGN_IN)
    }
    private fun authCheck(token: String) {
        // Instantiate the RequestQueue.
        val queue = newRequestQueue(this)
        val url = "https://pubsub.pubnub.com/v1/blocks/sub-key/sub-c-87dbd99c-e470-11e8-8d80-3ee0fe19ec50/google?token=$token"
        // Request a string response from the provided URL.
        val stringRequest = StringRequest(
            Request.Method.GET, url,
            Response.Listener<String> { response ->
                // Display the first 500 characters of the response string.
                Log.d("Response: ", response)
            },
            Response.ErrorListener {Log.d("Response: ", "Didn't Work!")})
        // Add the request to the RequestQueue.
        queue.add(stringRequest)
    }
}
```

Dzięki powyższemu kodowi Twoja aplikacja jest teraz w stanie uwierzytelnić i zweryfikować użytkownika! Po pomyślnym uwierzytelnieniu następnym krokiem jest pobranie tokena dostępu. Proces ten jest dość podobny do poprzedniego, ale tym razem należy wysłać żądanie `HTTP POST` do adresu URL tokena - `https://www.googleapis.com/oauth2/v4/token`. Można to zrobić za pomocą JavaScript, a kod można znaleźć na GitHub w celach informacyjnych.

Funkcja PubNub może wyglądać następująco:

```js
export default (request, response) => {
    const pubnub = require('pubnub');
    const xhr = require('xhr');
    let headersObject = request.headers;
    let paramsObject = request.params;
    let methodString = request.method;
    let bodyString = request.body;
    // Set the status code - by default it would return 200
    response.status = 200;
    // Set the headers the way you like
    
    var client_id = "your google client id"
    var client_secret = "your google client secret";
    var redirect = "https://pubsub.pubnub.com/v1/blocks/sub-key/sub-c-87dbd99c-e470-11e8-8d80-3ee0fe19ec50/Auth";
    
    response.headers['X-Custom-Header'] = 'CustomHeaderValue';
    var dataString = `client_id=${client_id}&client_secret=${client_secret}&redirect_uri=${redirect}&grant_type=authorization_code&code=CODE`;
    var url = `https://www.googleapis.com/oauth2/v4/token${dataString}`;
    var options = {
        "method": 'POST',
        "body": dataString,
    };
    
    console.log(dataString);
    return xhr.fetch(url, options).then((x) => {
        const body = JSON.parse(x.body);
        console.log(body);
         return response.send(body);
    }).catch((err) => {
        // console.log(err)
        return response.send("Malformed JSON body.");
    });
};
```

Pamiętaj, że musisz uzyskać [kod autoryzacji](https://developers.google.com/identity/sign-in/android/backend-auth) od użytkownika końcowego systemu Android, co możesz osiągnąć, dodając ten kod do pliku `MainActivity.kt`:

```js
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
try {
    GoogleSignInAccount account = task.getResult(ApiException.class);
    String authCode = account.getServerAuthCode();
    // Show signed-un UI
    updateUI(account);
    // TODO(developer): send code to server and exchange for access/refresh/ID tokens
} catch (ApiException e) {
    Log.w(TAG, "Sign-in failed", e);
    updateUI(null);
}
```

![](https://www.pubnub.com/cdn/3prze68gbwl1/asset-17suaysk1qa1jgc/58eca79bde501d62117171964a0f2a36/Google-Oauth-Sign-in.gif?w=700&h=550)

W ten sposób jesteś na dobrej drodze do wdrożenia logowania Google przy użyciu OAuth 2.0 w swojej aplikacji na Androida, zapewniając płynną obsługę i bezpieczeństwo aplikacji.

Po przetestowaniu aplikacji w otwartym Internecie, powinieneś być w stanie przejść przez cały proces logowania bez żadnych problemów. Proces ten może obejmować uwierzytelnianie Google OAuth, które obejmuje różne zakresy lub uprawnienia, które można ustawić dla aplikacji. Pamiętaj, że doświadczenie użytkownika powinno być płynne.

Teraz, gdy przeszedłeś przez wszystkie kroki, powinieneś lepiej zrozumieć różnicę między uwierzytelnianiem i autoryzacją opartą na identyfikatorze klienta OAuth. Opierając się na tej wiedzy, możesz zacząć badać, co możesz zrobić po zalogowaniu się użytkownika za pośrednictwem ekranu zgody OAuth.

Nazwa pakietu w zestawie SDK po stronie klienta, niezależnie od tego, czy jest to JavaScript, Kotlin, czy natywna dla innej platformy, powinna być zgodna z nazwą zarejestrowaną w projekcie Google Cloud. Jeśli jakakolwiek zawartość zewnętrzna nie jest dostępna na tej stronie, można ją również wyświetlić pod adresem [https://pubsub-quickstart-app.pubnub.com/signup](https://pubsub-quickstart-app.pubnub.com/signup). Ta strona powinna zademonstrować prawidłowe użycie przekierowań URI i parametrów wywołania zwrotnego wymaganych dla OAuth.

**Potrzebujesz pomocy PubNub?**
-------------------------------

Nasza platforma oferuje programistom zasoby do tworzenia, dostarczania i zarządzania interaktywnością w czasie rzeczywistym dla aplikacji internetowych, aplikacji mobilnych, aplikacji komputerowych i urządzeń IoT. Angażuj użytkowników za pomocą powiadomień lub twórz prywatne aplikacje Firebase z unikalnymi identyfikatorami dla zaawansowanych interakcji.

Szkieletem naszej platformy jest największa w branży i najbardziej skalowalna brzegowa sieć przesyłania wiadomości w czasie rzeczywistym. Oparta na usługach Google Cloud i zintegrowana z przeglądarką Chrome w celu zapewnienia dodatkowych możliwości, ma ponad 15 punktów obecności na całym świecie, obsługuje 800 milionów aktywnych użytkowników miesięcznie i zapewnia niezawodność na poziomie 99,999%, dzięki czemu nie musisz się martwić o przestoje, limity współbieżności lub opóźnienia spowodowane skokami ruchu.

### **Jak rozpocząć pracę z PubNub**

Zapoznaj się z podstawowymi koncepcjami każdej aplikacji opartej na PubNub w mniej niż 5 minut, sprawdzając [Live Tour](https://www.pubnub.com/tour/introduction/). OpenID może być ważną częścią tych koncepcji. Zarejestruj [konto Pub](https://admin.pubnub.com/signup/) Nub, aby uzyskać natychmiastowy dostęp do kluczy PubNub za darmo. [Dokumentacja](https://www.pubnub.com/docs) PubNub poprowadzi Cię przez proces instalacji i konfiguracji, w tym fragmenty kodu lub "fragmenty" ze szczegółowymi parametrami, niezależnie od przypadku użycia lub preferowanego [zestawu SDK](https://www.pubnub.com/docs).

#### Treść

Jaka jest[różnica między uwierzytelnianiem a autoryzacją?](#h-0)[Jak Authn i Authz pasują do OuthUwierzytelnianie](#h-1)[za pomocą Google Sign-in na AndroidzieDodawanie](#h-2)[przycisku Google](#h-3)[Sign-inPotrzebujesz pomocy PubNub?](#h-4)[Jak zacząć korzystać z PubNub](#h-5)?

Jak PubNub może ci pomóc?
=========================

Ten artykuł został pierwotnie opublikowany na [PubNub.com](https://pubnub.com/blog/creating-a-secure-login-on-android-using-google-oauth/)

Nasza platforma pomaga programistom tworzyć, dostarczać i zarządzać interaktywnością w czasie rzeczywistym dla aplikacji internetowych, aplikacji mobilnych i urządzeń IoT.

Podstawą naszej platformy jest największa w branży i najbardziej skalowalna sieć komunikacyjna w czasie rzeczywistym. Dzięki ponad 15 punktom obecności na całym świecie obsługującym 800 milionów aktywnych użytkowników miesięcznie i niezawodności na poziomie 99,999%, nigdy nie będziesz musiał martwić się o przestoje, limity współbieżności lub jakiekolwiek opóźnienia spowodowane skokami ruchu.

Poznaj PubNub
-------------

Sprawdź [Live Tour](https://www.pubnub.com/tour/introduction/), aby zrozumieć podstawowe koncepcje każdej aplikacji opartej na PubNub w mniej niż 5 minut.

Rozpocznij konfigurację
-----------------------

Załóż [konto](https://admin.pubnub.com/signup/) PubNub, aby uzyskać natychmiastowy i bezpłatny dostęp do kluczy PubNub.

Rozpocznij
----------

[Dokumenty](https://www.pubnub.com/docs) PubNub pozwolą Ci rozpocząć pracę, niezależnie od przypadku użycia lub [zestawu SDK](https://www.pubnub.com/docs).