Autenticazione su indossabili

Le app per Wear OS possono essere eseguite in modo autonomo, senza un'app complementare. Ciò significa che un'app per Wear OS deve gestire autonomamente l'autenticazione quando accede ai dati da internet. Tuttavia, le piccole dimensioni dello schermo e le ridotte funzionalità di inserimento dell'orologio limitano le opzioni di autenticazione che un'app Wear OS può utilizzare.

Questa guida illustra i metodi di autenticazione consigliati per le app Wear OS, nonché le alternative quando questi metodi non sono adatti al caso d'uso di un'app.

Per scoprire di più su come progettare un'esperienza di accesso ottimale, consulta la guida sull'esperienza utente di accesso.

Modalità Ospite

Non richiedere l'autenticazione per tutte le funzionalità. Fornisci invece all'utente il maggior numero possibile di funzionalità senza che debba accedere.

Gli utenti potrebbero scoprire e installare la tua app per Wear senza aver utilizzato l'app mobile, quindi potrebbero non avere un account e non sapere quali funzionalità offre. Assicurati che la funzionalità della modalità ospite metta in evidenza con precisione le funzionalità della tua app.

Alcuni dispositivi potrebbero rimanere sbloccati più a lungo

Sui dispositivi supportati con Wear OS 5 o versioni successive, il sistema rileva se l'utente indossa il dispositivo sul polso. Se l'utente disattiva il rilevamento del polso e poi toglie il dispositivo dal polso, il sistema mantiene il dispositivo sbloccato per un periodo di tempo più lungo rispetto a quanto farebbe altrimenti.

Se la tua app richiede un livello di sicurezza più elevato, ad esempio quando mostra dati potenzialmente sensibili o privati, controlla innanzitutto se il rilevamento del polso è attivo:

val wristDetectionEnabled =
        isWristDetectionAutoLockingEnabled(applicationContext)

Se il valore restituito di questo metodo è false, chiedi all'utente di accedere a un account nella tua app prima di visualizzare contenuti specifici per l'utente.

Metodi di autenticazione consigliati

Utilizza i seguenti metodi di autenticazione per consentire alle app Wear OS autonome di ottenere le credenziali di autenticazione dell'utente.

Passare i token utilizzando il livello dati

L'app complementare per smartphone può trasferire in sicurezza i dati di autenticazione all'app Wear OS utilizzando il livello dati per dispositivi indossabili. Trasferisci le credenziali come messaggi o elementi di dati.

Questo tipo di autenticazione in genere non richiede alcuna azione da parte dell'utente. Tuttavia, evita di eseguire l'autenticazione senza informare l'utente che sta accedendo. Puoi informare l'utente utilizzando una schermata semplice e ignorabile che gli mostra che il suo account è in fase di trasferimento dal dispositivo mobile.

Importante: la tua app Wear deve offrire almeno un altro metodo di autenticazione, perché questa opzione funziona solo su smartwatch accoppiati ad Android quando è installata l'app mobile corrispondente. Fornire un metodo di autenticazione alternativo per gli utenti che non dispongono dell'app mobile corrispondente o il cui dispositivo Wear OS è accoppiato a un dispositivo iOS.

Passa i token utilizzando il livello dati dall'app mobile, come mostrato nell'esempio seguente:

val token = "..." // Auth token to transmit to the wearable device.
val dataClient: DataClient = Wearable.getDataClient(context)
val putDataReq: PutDataRequest = PutDataMapRequest.create("/auth").run {
    dataMap.putString("token", token)
    asPutDataRequest()
}
val putDataTask: Task<DataItem> = dataClient.putDataItem(putDataReq)

Ascolta gli eventi di modifica dei dati nell'app per smartwatch come mostrato nell'esempio seguente:

val dataClient: DataClient = Wearable.getDataClient(context)
dataClient.addListener{ dataEvents ->
    dataEvents.forEach { event ->
        if (event.type == DataEvent.TYPE_CHANGED) {
            val dataItemPath = event.dataItem.uri.path ?: ""
            if (dataItemPath.startsWith("/auth")) {
                val token = DataMapItem.fromDataItem(event.dataItem).dataMap.getString("token")
                // Display interstitial screen to notify the user they are being signed in.
                // Then, store the token and use it in network requests.
            }
        }
    }
}

Per ulteriori informazioni sull'utilizzo del livello dati per i dispositivi indossabili, consulta Inviare e sincronizzare i dati su Wear OS.

Utilizzare OAuth 2.0

Wear OS supporta due flussi basati su OAuth 2.0, descritti nelle sezioni seguenti:

  • Concessione del codice di autorizzazione con Proof Key for Code Exchange (PKCE), come definito in RFC 7636
  • Concessione dell'autorizzazione del dispositivo, come definito nel RFC 8628

Nota: per assicurarti che l'app non si arresti quando lo smartwatch passa alla modalità Ambient, attiva la funzionalità Sempre attivo utilizzando AmbientModeSupport.attach nell'attività che esegue l'autenticazione. Per ulteriori informazioni sulle best practice in modalità Ambient, consulta Mantenere l'app visibile su Wear.

Proof Key for Code Exchange (PKCE)

Per utilizzare efficacemente PKCE, usa RemoteAuthClient.

Per eseguire una richiesta di autenticazione dalla tua app Wear OS a un provider OAuth, crea un oggetto OAuthRequest. Questo oggetto è costituito da un URL all'endpoint OAuth per ottenere un token e da un oggetto CodeChallenge. Il seguente codice mostra un esempio di creazione di una richiesta di autenticazione:

val request = OAuthRequest.Builder(this.applicationContext)
    .setAuthProviderUrl(Uri.parse("https://...."))
    .setClientId(clientId)
    .setCodeChallenge(codeChallenge)
    .build()

Dopo aver creato la richiesta di autenticazione, inviala all'app complementare utilizzando il metodo sendAuthorizationRequest():

val client = RemoteAuthClient.create(this)
client.sendAuthorizationRequest(request,
    { command -> command?.run() },
    object : RemoteAuthClient.Callback() {
        override fun onAuthorizationResponse(
            request: OAuthRequest,
            response: OAuthResponse
        ) {
            // Extract the token from the response, store it and use it in network requests.
        }

        override fun onAuthorizationError(errorCode: Int) {
            // Handle error
        }
    }
)

Questa richiesta attiva una chiamata all'app complementare, che presenta un'interfaccia utente di autorizzazione in un browser web sul cellulare dell'utente. Il provider OAuth 2.0 autentica l'utente e ottiene il suo consenso per le autorizzazioni richieste. La risposta viene inviata all'URL di reindirizzamento generato automaticamente.

Dopo un'autorizzazione riuscita o non riuscita, il server OAuth 2.0 reindirizza all'URL specificato nella richiesta. Se l'utente approva la richiesta di accesso, la risposta contiene un codice di autorizzazione. Se l'utente non approva la richiesta, la risposta contiene un messaggio di errore.

La risposta è sotto forma di stringa di query e ha il seguente aspetto:

  https://wear.googleapis.com/3p_auth/com.your.package.name?code=xyz
  https://wear.googleapis-cn.com/3p_auth/com.your.package.name?code=xyz

Viene caricata una pagina che indirizza l'utente all'app complementare. L'app complementare verifica l'URL di risposta e inoltra la risposta all'app per smartwatch di terze parti utilizzando l'API onAuthorizationResponse.

L'app dello smartwatch può quindi scambiare il codice di autorizzazione con un token di accesso.

Nota:una volta creato il file OAuthRequest, puoi trovare l'URL di reindirizzamento accedendo a redirectUrl.

Concesione dell'autorizzazione del dispositivo

Quando utilizza la concessione dell'autorizzazione del dispositivo, l'utente apre l'URI di verifica su un altro dispositivo. Il server di autorizzazione chiede all'utente di approvare o rifiutare la richiesta.

Per semplificare questa procedura, utilizza un RemoteActivityHelper per aprire una pagina web sul dispositivo mobile accoppiato dell'utente, come mostrato nell'esempio seguente:

// Request access from the authorization server and receive Device Authorization Response.
val verificationUri = "..." // Extracted from the Device Authorization Response.
RemoteActivityHelper.startRemoteActivity(
    this,
    Intent(Intent.ACTION_VIEW)
        .addCategory(Intent.CATEGORY_BROWSABLE)
        .setData(Uri.parse(verificationUri)),
    null
)
// Poll the authorization server to find out if the user completed the user authorization
// step on their mobile device.

Se hai un'app per iOS, utilizza link universali per intercettare questo intent nella tua app anziché fare affidamento sul browser per autorizzare il token.

Altri metodi di autenticazione

Wear OS supporta metodi di accesso aggiuntivi, descritti nelle sezioni seguenti.

Accedi con Google

Accedi con Google consente all'utente di accedere con il proprio Account Google esistente. Offre la migliore esperienza utente ed è facile da supportare, soprattutto se lo hai già implementato nelle tue app per dispositivi palmari.

Dopo i metodi di autenticazione consigliati descritti in precedenza, Accedi con Google è la soluzione preferita successiva perché funziona bene anche su iOS. La sezione seguente descrive come completare un'integrazione di base di Accedi con Google.

Prerequisiti

Prima di poter iniziare a integrare Accedi con Google nella tua app per Wear OS, devi configurare un progetto della console API di Google e configurare il progetto Android Studio. Per ulteriori informazioni, consulta Iniziare a integrare Accedi con Google nella tua app per Android.

Se utilizzi Accedi con Google con un'app o un sito che comunicate con un server di backend, sono previsti due prerequisiti aggiuntivi:

  • Crea un ID client per l'applicazione web OAuth 2.0 per il tuo server di backend. Questo ID client è diverso dall'ID client della tua app. Per maggiori informazioni, consulta Abilitare l'accesso lato server.
  • Identifica in modo sicuro l'utente che ha eseguito l'accesso al server inviando il token ID dell'utente tramite HTTPS. Per scoprire come autenticare l'utente sul server di backend, consulta Autenticarsi con un server di backend.

Integrare Accedi con Google nella tua app

Per integrare Accedi con Google nella tua app per Wear OS, esamina e implementa i seguenti passaggi, descritti nel dettaglio nelle sezioni che seguono:

  1. Configura Accedi con Google.
  2. Aggiungi un pulsante Accedi con Google.
  3. Avvia il flusso di accesso quando viene toccato il pulsante di accesso.

Configurare Accedi con Google e creare l'oggetto GoogleApiClient

Nel metodo onCreate() dell'attività di accesso, configura Accedi con Google in modo che richieda i dati utente richiesti dalla tua app. Quindi, crea un oggetto GoogleApiClient con accesso all'API Accedi con Google e alle opzioni specificate. Questi passaggi sono mostrati nell'esempio seguente:

public class MyNewActivity extends AppCompatActivity {

    private static final int RC_SIGN_IN = 9001;

    private GoogleSignInClient mSignInClient;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        GoogleSignInOptions options =
                new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                        .build();

        mSignInClient = GoogleSignIn.getClient(this, options);
    }
}

Aggiungere un pulsante di accesso con Google all'app

Per aggiungere un pulsante Accedi con Google:

  1. Aggiungi SignInButton al layout dell'app:
  2.  <com.google.android.gms.common.SignInButton
     android:id="@+id/sign_in_button"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" />
  3. Nel metodo onCreate() della tua app, registra il OnClickListener del pulsante per far eseguire l'accesso all'utente quando viene toccato:
  4. Kotlin

    findViewById<View>(R.id.sign_in_button).setOnClickListener(this)

    Java

    findViewById(R.id.sign_in_button).setOnClickListener(this);

Creare un'intenzione di accesso e avviare il flusso di accesso

Gestisci i tocchi del pulsante di accesso nel metodo onCLick() creando un'intenzione di accesso con il metodo getSignInIntent(). Quindi avvia l'intenzione con il metodo startActivityForResult().

Intent intent = mSignInClient.getSignInIntent();
startActivityForResult(intent, RC_SIGN_IN);

All'utente viene chiesto di selezionare un Account Google con cui accedere. Se hai richiesto ambiti oltre a profilo, email e OpenID, all'utente viene chiesto anche di concedere l'accesso a queste risorse.

Infine, nel metodo onActivityResult dell'attività, recupera il risultato dell'accesso con getSignInResultFromIntent. Dopo aver recuperato il risultato dell'accesso, puoi verificare se l'accesso è andato a buon fine utilizzando il metodo isSuccess. Se l'accesso va a buon fine, puoi chiamare il metodo getSignInAccount per ottenere un oggetto GoogleSignInAccount contenente informazioni sull'utente che ha eseguito l'accesso, ad esempio il nome. Questi passaggi sono illustrati nell'esempio seguente:

Kotlin

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    super.onActivityResult(requestCode, resultCode, data)

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...).
    if (requestCode == RC_SIGN_IN) {
        Auth.GoogleSignInApi.getSignInResultFromIntent(data)?.apply {
            if (isSuccess) {
                // Get account information.
                fullName = signInAccount?.displayName
                mGivenName = signInAccount?.givenName
                mFamilyName = signInAccount?.familyName
                mEmail = signInAccount?.email
            }
        }
    }
}

Java

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...).
    if (requestCode == RC_SIGN_IN) {
        GoogleSignInResult signInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        if (signInResult.isSuccess()) {
            GoogleSignInAccount acct = signInResult.getSignInAccount();

            // Get account information.
            fullName = acct.getDisplayName();
            givenName = acct.getGivenName();
            familyName = acct.getFamilyName();
            email = acct.getEmail();
        }
    }
}

Per visualizzare un'app di esempio che implementa Accedi con Google, consulta l' Esempio di Accedi con Google per Horologist su GitHub.

Autenticazione tramite codice personalizzato

Come alternativa ai metodi di autenticazione descritti in precedenza, puoi richiedere all'utente di autenticarsi da un altro dispositivo, ad esempio uno smartphone o un tablet, e ottenere un codice numerico temporaneo. L'utente inserisce quindi il codice sul proprio dispositivo Wear OS per confermare la propria identità e riceve un token di autenticazione.

Questo flusso di autenticazione utilizza il modulo di accesso della tua app o integra manualmente un metodo di accesso del provider di autenticazione di terze parti nel codice dell'app. Sebbene questo metodo di autenticazione richieda un intervento manuale e un impegno aggiuntivo per renderlo più sicuro, puoi utilizzarlo se hai bisogno di autenticazione in un momento precedente nelle tue app Wear OS autonome.

Il flusso di autenticazione per questa configurazione funziona nel seguente modo:

  1. L'utente esegue un'azione con l'app Wear OS che richiede l'autorizzazione.
  2. L'app Wear OS mostra all'utente una schermata di autenticazione e lo invita a inserire un codice da un URL specificato.
  3. L'utente passa a un dispositivo mobile, un tablet o un PC, quindi avvia un browser, accede all'URL specificato nell'app Wear OS e accede.
  4. L'utente riceve un codice numerico temporaneo che inserisce nella schermata di autenticazione dell'app Wear OS utilizzando la tastiera integrata in Wear OS:

  5. Da questo punto in poi, puoi utilizzare il codice inserito come prova che si tratta dell'utente corretto e scambiarlo con un token di autenticazione archiviato e protetto sul dispositivo Wear OS per le chiamate autenticate future.

Nota:il codice generato dall'utente deve essere puramente numerico e non può contenere caratteri alfabetici.

Questo flusso di autenticazione è rappresentato nel seguente grafico: