Démarrer avec AWS

Créer une application Android

Créer une application Android simple avec AWS Amplify

Module 3 : Ajouter une authentification

Dans ce module, vous allez utiliser la ligne d'interface de commande Amplify et des bibliothèques pour configurer et ajouter une authentification à votre application.

Introduction

La prochaine fonction que vous ajouterez est l'authentification de l'utilisateur. Dans ce module, vous apprendrez comment authentifier un utilisateur avec l'interface de ligne de commande et les bibliothèques Amplify, en exploitant Amazon Cognito, un fournisseur géré d'identités des utilisateurs.

Vous apprendrez également à utiliser l'interface utilisateur hébergée Cognito pour présenter un flux complet d'authentification des utilisateurs, ce qui permettra à ces derniers de s'inscrire, de se connecter et de réinitialiser leur mot de passe avec seulement quelques lignes de code.

L'utilisation d'une « interface utilisateur hébergée » signifie que l'application exploite les pages web de Cognito pour les flux d'interface utilisateur de connexion et d'inscription. L'utilisateur de l'application est redirigé vers une page web hébergée par Cognito, puis il est redirigé à nouveau vers l'application après s'être connecté. Bien entendu, Cognito et Amplify prennent également en charge l'interface utilisateur native et vous pouvez suivre les instructions de cet atelier pour en savoir plus sur l'interface utilisateur d'authentification personnalisée.

Ce que vous apprendrez

  • Créer et déployer un service d'authentification
  • Configurer une application Android afin d'inclure une authentification d'interface utilisateur hébergée

Concepts clés

Bibliothèques Amplify  : ces bibliothèques vous permettent d'interagir avec les services AWS à partir d'une application mobile ou web.

Authentification : au niveau logiciel, l'authentification correspond au processus de vérification et de gestion de l'identité d'un utilisateur avec un service d'authentification ou d'une API.

 Durée nécessaire

10 minutes

 Services utilisés

Implémentation

  • Création du service d'authentification

    Pour créer le service d'authentification, ouvrez un terminal et exécutez cette commande :

    amplify add auth
    
    ? Do you want to use the default authentication and security configuration? Select Default configuration with Social Provider and press enter
    ? How do you want users to be able to sign in? Select the default Username and press enter
    ? Do you want to configure advanced settings? Select the default No, I am done and press enter
    ? What domain name prefix do you want to use? Select the default and press enter
    Enter your redirect signin URI: type gettingstarted:// and press enter
    ? Do you want to add another redirect signin URI? Select the default N and press enter
    Enter your redirect signout URI: type gettingstarted:// and press enter
    ? Do you want to add another redirect signout URI? Select the default N and press enter
    ? Select the social providers you want to configure for your user pool: do not select any provider and press enter

    Vous saurez que la configuration est réussie lorsque vous verrez ce message s'afficher (le nom exact de la ressource peut être différent) :

    Successfully added resource androidgettingstartedfc5a4717 locally
  • Déploiement du service d'authentification

    Une fois le service d'authentification configuré localement, nous pouvons le déployer dans le cloud. Dans un terminal, exécutez cette commande dans votre répertoire de projet :

    amplify push
    
    # press Y when asked to continue

    Après un certain temps, vous devriez voir apparaître le message suivant :

    ✔ All resources are updated in the cloud
    
    Hosted UI Endpoint: https://androidgettingstarted-dev.auth.eu-central-1.amazoncognito.com/
    Test Your Hosted UI Endpoint: https://androidgettingstarted-dev.auth.eu-central-1.amazoncognito.com/login?response_type=code&client_id=1234567890&redirect_uri=gettingstarted://
  • Ajout de la bibliothèque d'authentification Amplify au projet

    Avant d'accéder au code, revenez sous Android Studio et ajoutez cette dépendance au 'build.gradle' de votre module avec les autres implémentations 'amplifyframework' ajoutées auparavant, puis cliquez sur Sync Now (Synchroniser maintenant) :

    dependencies {
        ...
        // Amplify core dependency
        implementation 'com.amplifyframework:core:1.4.0'
        implementation 'com.amplifyframework:aws-auth-cognito:1.4.0'
    }
  • Configuration de la bibliothèque d'authentification Amplify au moment de l'exécution

    De retour dans Android Studio, ouvrez le fichier Backend.kt. Dans la classe Backend, ajoutez une ligne au code d'initialisation Amplify que nous avons ajouté à la section précédente, avec la méthode initialize().

    Le bloc de code complet doit ressembler à ceci :

    // inside Backend class
    fun initialize(applicationContext: Context) : Backend {
        try {
            Amplify.addPlugin(AWSCognitoAuthPlugin())
            Amplify.configure(applicationContext)
    
            Log.i(TAG, "Initialized Amplify")
        } catch (e: AmplifyException) {
            Log.e(TAG, "Could not initialize Amplify", e)
        }
        return this
    }

    N'oubliez pas d'ajouter les instructions d'import. Android Studio s'en charge pour vous de façon automatique (sur Mac, faites Alt + Entrée sur chaque erreur détectée par l'éditeur de code).

    Comme à l'étape précédente, ajoutez les instructions d'import requises pour chaque définition de classe manquante (Alt+Entrée sur les mots en rouge).

    Pour vérifier que tout fonctionne comme prévu, générez le projet. Cliquez dans le menu Build (Générer) et sélectionnez Make Project (Créer le projet), ou, sur Mac, appuyez sur ⌘F9. Il ne devrait y avoir aucune erreur.

  • Déclenchez l'authentification au démarrage

    Les autres modifications de code suivent le statut d'un utilisateur (est-il connecté ou non ?) et déclenchent l'interface utilisateur SignIn/SignUp lorsqu'un utilisateur clique sur un icône cadenas.

    a. Ajout des méthodes signIn et signOut
    Dans la classe backend, ajoutez les quatre méthodes suivantes :
    private fun updateUserData(withSignedInStatus : Boolean) {
        UserData.setSignedIn(withSignedInStatus)
    }
    
    fun signOut() {
        Log.i(TAG, "Initiate Signout Sequence")
    
        Amplify.Auth.signOut(
            { Log.i(TAG, "Signed out!") },
            { error -> Log.e(TAG, error.toString()) }
        )
    }
    
    fun signIn(callingActivity: Activity) {
        Log.i(TAG, "Initiate Signin Sequence")
    
        Amplify.Auth.signInWithWebUI(
            callingActivity,
            { result: AuthSignInResult ->  Log.i(TAG, result.toString()) },
            { error: AuthException -> Log.e(TAG, error.toString()) }
        )
    }

    Ensuite, ajoutez les instructions d'import requises pour chaque définition de classe manquante (Alt + Entrée sur les mots en rouge). Lorsque vous avez le choix entre plusieurs classes, assurez-vous de sélectionner celle qui se trouve dans le package Amplify, comme illustré dans la capture d'écran ci-dessous.

    AndroidAppTutorial_Modiule3_Image1

    Vous remarquerez que nous ne mettons pas à jour l'indicateur UserData.isSignedIn avec ces méthodes, cela sera fait dans la section suivante.

    b. Ajout d'un écouteur du hub d'authentification

    Pour suivre les changements de statut d'authentification, nous ajoutons un code pour nous abonner aux événements d'authentification envoyés par Amplify. Nous initialisons le hub dans la méthode Backend.initialize().

    Lorsqu'un événement d'authentification est reçu, nous appelons la méthode updateUserData(). Cette méthode permet de garder l'objet UserData synchronisé. La propriété UserData.isSignedIn est un LiveData<Boolean>, cela signifie que les observateurs qui sont abonnés à cette propriété seront notifiés lorsque la valeur change. Nous utilisons ce mécanisme pour rafraîchir automatiquement l'interface utilisateur. Vous pouvez en savoir plus sur LiveData dans le document Android.

    Nous ajoutons également un code pour vérifier le statut d'authentification précédent au moment du démarrage de l'application. Lorsque l'application démarre, elle vérifie si une session Cognito existe déjà et met à jour UserData en conséquence.

    Dans Backend.initialize(), ajoutez le code suivant après le bloc try / catch et avant l'instruction de retour.

    // in Backend.initialize() function, after the try/catch block but before the return statement 
    
    Log.i(TAG, "registering hub event")
    
    // listen to auth event
    Amplify.Hub.subscribe(HubChannel.AUTH) { hubEvent: HubEvent<*> ->
    
        when (hubEvent.name) {
            InitializationStatus.SUCCEEDED.toString() -> {
                Log.i(TAG, "Amplify successfully initialized")
            }
            InitializationStatus.FAILED.toString() -> {
                Log.i(TAG, "Amplify initialization failed")
            }
            else -> {
                when (AuthChannelEventName.valueOf(hubEvent.name)) {
                    AuthChannelEventName.SIGNED_IN -> {
                        updateUserData(true)
                        Log.i(TAG, "HUB : SIGNED_IN")
                    }
                    AuthChannelEventName.SIGNED_OUT -> {
                        updateUserData(false)
                        Log.i(TAG, "HUB : SIGNED_OUT")
                    }
                    else -> Log.i(TAG, """HUB EVENT:${hubEvent.name}""")
                }
            }
        }
    }
    
    Log.i(TAG, "retrieving session status")
    
    // is user already authenticated (from a previous execution) ?
    Amplify.Auth.fetchAuthSession(
        { result ->
            Log.i(TAG, result.toString())
            val cognitoAuthSession = result as AWSCognitoAuthSession
            // update UI
            this.updateUserData(cognitoAuthSession.isSignedIn)
            when (cognitoAuthSession.identityId.type) {
                AuthSessionResult.Type.SUCCESS ->  Log.i(TAG, "IdentityId: " + cognitoAuthSession.identityId.value)
                AuthSessionResult.Type.FAILURE -> Log.i(TAG, "IdentityId not present because: " + cognitoAuthSession.identityId.error.toString())
            }
        },
        { error -> Log.i(TAG, error.toString()) }
    )

    Pour vérifier que tout fonctionne comme prévu, générez le projet. Cliquez dans le menu Build (Générer) et sélectionnez Make Project (Créer le projet), ou, sur Mac, appuyez sur ⌘F9. Il ne devrait y avoir aucune erreur.

    c. Mise à jour du code de l'interface utilisateur

    Le dernier changement dans le code est lié à l'interface utilisateur, nous ajoutons un bouton FloatingActionButton à l'activité principale.

    Sous res/layout, ouvrez activity_main.xml et remplacez le FloatingActionButton existant par celui-ci :

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fabAuth"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_gravity="bottom|end"
        android:layout_margin="@dimen/fab_margin"
        android:src="@drawable/ic_baseline_lock"
        app:fabCustomSize="60dp"
        app:fabSize="auto"
        />

    Ajoutez un icône du cadenas sous res/drawable. Cliquez droit sur drawable, sélectionnez New (Nouveau), puis Vector Asset (Ressource vectorielle). Choisissez l'icône cadenas dans le clipart et saisissez ic_baseline_lock (sans _24) comme nom et sélectionnez l'icône du cadenas fermé dans le Clip Art. Cliquez sur Next (Suivant) puis Finish (Terminer).

    Répétez l'opération avec l'icône du cadenas ouvert.

    AndroidAppTutorial_Modiule3_Image2
    AndroidAppTutorial_Modiule3_Image3

    Une fois terminé, vous devrez trouver les fichiers suivants dans votre répertoire drawable :

    AndroidAppTutorial_Modiule3_Image4

    Maintenant, reliez le bouton nouvellement créé dans le code. Sous java/com.example.androidgettingstarted/, ouvrez MainActivity.kt et ajoutez le code suivant.

    // anywhere in the MainActivity class
    private fun setupAuthButton(userData: UserData) {
    
        // register a click listener
        fabAuth.setOnClickListener { view ->
    
            val authButton = view as FloatingActionButton
    
            if (userData.isSignedIn.value!!) {
                authButton.setImageResource(R.drawable.ic_baseline_lock_open)
                Backend.signOut()
            } else {
                authButton.setImageResource(R.drawable.ic_baseline_lock_open)
                Backend.signIn(this)
            }
        }
    }

    Toujours dans MainActivity, ajoutez le code suivant à la fin de la méthode onCreate() :

    setupAuthButton(UserData)
    
    UserData.isSignedIn.observe(this, Observer<Boolean> { isSignedUp ->
        // update UI
        Log.i(TAG, "isSignedIn changed : $isSignedUp")
    
        if (isSignedUp) {
            fabAuth.setImageResource(R.drawable.ic_baseline_lock_open)
        } else {
            fabAuth.setImageResource(R.drawable.ic_baseline_lock)
        }
    })

    Le code ci-dessus sauvegarde un observateur sur une valeur Userdata.isSignedIn. La fermeture est appelée lorsque la valeur de isSignedIn change. Pour le moment, il suffit de changer l'icône du cadenas : ouvert lorsque l'utilisateur est authentifié et fermé lorsque l'utilisateur n'a pas de session active.

    Pour vérifier que tout fonctionne comme prévu, générez le projet. Cliquez dans le menu Build (Générer) et sélectionnez Make Project (Créer le projet), ou, sur Mac, appuyez sur ⌘F9. Il ne devrait y avoir aucune erreur.

    d. Mise à jour de AndroidManifest.xml et MainActivity

    Pour terminer, nous devons nous assurer que notre application est lancée à la fin de la séquence d'authentification web, fournie par l'interface utilisateur hébergée par Cognito. Nous ajoutons une nouvelle activité dans le fichier manifest. L'activité est appelée après réception du schéma d'URI gettingstarted.

    Dans Android Studio, sous manifests, ouvrez AndroidManifest.xml et ajoutez l'activité suivante au sein de l'élément application.

        <activity
    android:name="com.amazonaws.mobileconnectors.cognitoauth.activities.CustomTabsRedirectActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
    
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
    
                <data android:scheme="gettingstarted" />
            </intent-filter>
        </activity>
    

    Sous java/com.example.androidgettingstarted/, ouvrez MainActivity.kt et ajoutez le code suivant n'importe où dans la classe.

    // MainActivity.kt
    // receive the web redirect after authentication
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        Backend.handleWebUISignInResponse(requestCode, resultCode, data)
    }

    Sous java/com.example.androidgettingstarted/, ouvrez Backend.kt et ajoutez le code suivant n'importe où dans la classe.

    // Backend.kt
    // pass the data from web redirect to Amplify libs 
    fun handleWebUISignInResponse(requestCode: Int, resultCode: Int, data: Intent?) {
        Log.d(TAG, "received requestCode : $requestCode and resultCode : $resultCode")
        if (requestCode == AWSCognitoAuthPlugin.WEB_UI_SIGN_IN_ACTIVITY_CODE) {
            Amplify.Auth.handleWebUISignInResponse(data)
        }
    }

    e. Développement et test

    Pour vérifier que tout fonctionne comme prévu, générez et exécutez le projet. Cliquez sur l'icône Exécuter ▶️ dans la barre d'outils ou tapez ^ R. Il ne devrait y avoir aucune erreur. L'application se lance et un bouton flottant cadenas fermé se trouve en bas à droite de l'écran.

    Voici le flux d'inscription complet.

    AndroidAppTutorial_Modiule3_Image5
    AndroidAppTutorial_Modiule3_Image6
    AndroidAppTutorial_Modiule3_Image7
    AndroidAppTutorial_Modiule3_Image8
    AndroidAppTutorial_Modiule3_Image9

Conclusion

Vous venez d'ajouter l'authentification des utilisateurs à votre application avec seulement quelques lignes de code. Dans le module suivant, nous allons ajouter une API à votre application.

Ce module vous a-t-il été utile ?

Merci
Merci de nous indiquer ce que vous avez aimé.
Fermer
Nous sommes désolés de vous décevoir.
Quelque chose est-il obsolète, déroutant ou inexact ? Aidez-nous à améliorer ce didacticiel en fournissant des commentaires.
Fermer

Ajouter une API GraphQL et une base de données