Para acceder a Atlas App Services, primero debe autenticar a un usuario con un proveedor de autenticación de App Services. Esta página describe cómo autenticar a los usuarios de App Services con el SDK de Kotlin de Realm. Consulte Autenticar y administrar usuarios en la documentación de App Services para obtener más información.
Importante
Requisitos de eliminación de cuentas de Google y Apple
Google Apple exige que las aplicaciones publicadas en sus respectivas App Stores ofrezcan a cualquier usuario que cree una cuenta la opción de eliminarla. Tanto si utiliza un método de autenticación que requiere el registro manual de un usuario, como la autenticación por correo electrónico y contraseña, como uno que crea un usuario automáticamente, como Iniciar sesión con Apple, debe implementar la eliminación de cuentas de usuario.
Usuarios de aplicación Services
Atlas App Services provides the following built-in authentication providers to log users in and out of a client app:
Anonymous users
Combinaciones de correo electrónico/contraseña
API keys
OAuth 2.0 through Facebook, Google, and Apple ID
JWT personalizado
Función personalizada
Tras iniciar sesión de forma exitosa, aplicación Services inicia una sesión de usuario para el usuario. App Services gestiona las sesiones con tokens de acceso y tokens de actualización, y el Kotlin SDK proporciona la lógica para gestionar los tokens y proporcionárselos en las solicitudes. Para obtener más información sobre la gestión de sesiones de usuario y tokens, consulte Sesiones de usuario en la documentación de Servicios de aplicación.
Una vez que cuentes con un usuario iniciado sesión, puedes:
Open a synced realm with the user's configuration object
Run a backend function as the logged-in user
Cerrar la sesión del usuario (consulte la sección Cerrar sesión de un usuario)
También puedes iniciar sesión simultáneamente con varios usuarios en una aplicación desde un mismo dispositivo. Consulta "Administrar aplicaciones multiusuario - SDK de Kotlin" para obtener más información.
Requisitos previos
To authenticate users through Atlas App Services, you must have an App Services App with one or more authentication providers enabled.
To set up an App Services App with authentication providers, complete the following:
Habilitar y configurar proveedores de autenticación en la documentación de App Services
Tip
Puedes habilitar varios proveedores de autenticación. Si un usuario se autentica utilizando más de un método, puede vincular las identidades del usuario para cada método a una única cuenta de usuario.
Register and Create a New User Account
Atlas App Services registers a user differently depending on the authentication provider:
Si está utilizando autenticación por correo electrónico/contraseña, los usuarios deben primero registrar y confirmar su correo electrónico y contraseña antes de que puedan autenticarse.
Si usa Google, Facebook, Apple o JWT personalizado, el registro lo gestionan estos servicios de terceros.
If you are using anonymous authentication, you don't need to register. Anonymous users do not require registration.
La primera vez que el usuario se autentica correctamente en su aplicación, Atlas App Services crea automáticamente un objeto Usuario, que contiene un identificador único y metadatos de usuario específicos del proveedor. Para obtener más información sobre el objeto Usuario que App Services proporciona al SDK de Kotlin, consulte "Leer metadatos de usuario" en la documentación de App Services.
Iniciar sesión de un usuario
Para autenticar e iniciar sesión en la aplicación, primero instancia un objeto Credentials que contenga las credenciales asociadas al proveedor de autenticación y luego pásalo a app.login(). Cada proveedor de autenticación corresponde a un método auxiliar estático que se utiliza para instanciarlo. Credentials objetos para ese proveedor de autenticación.
// Instantiate your App Services App val app = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { // Log in the user with the credentials associated // with the authentication provider // If successful, returns an authenticated `User` object val user = app.login(credentials) // ... work with the user ... }
Si tiene éxito, app.login() retorna un objeto User. En el evento de un fallo, app.login() produce una excepción de tipo AppException.
Tip
Puedes obtener el tipo de proveedor de autenticación que se utilizó para iniciar sesión de un usuario a través de la propiedad user.provider. Si el usuario ha cerrado sesión actualmente, se devuelve el proveedor más reciente utilizado para iniciar sesión.
Anonymous
La autenticación anónima permite a los usuarios iniciar sesión en tu aplicación con cuentas a corto plazo que no almacenan información personal persistente. Se puede usar esto para permitir que los usuarios prueben tu aplicación antes de registrarse para una cuenta o mientras desarrollan y prueban la aplicación. Los usuarios anónimos no requieren registro. Consulta Autenticación Anónima en la documentación de App Services para obtener más información.
Para iniciar sesión con autenticación anónima, crea una credencial anónima llamando a Credentials.anonymous(), y luego pasa la credencial generada a app.login():
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { val anonymousCredentials = Credentials.anonymous() val user = app.login(anonymousCredentials) }
By default, the Kotlin SDK reuses the same anonymous user if that user has not logged out. If you want to create more than one anonymous user, set reuseExisting = false when logging in with additional anonymous credentials:
// Logs in with an anonymous user val anonUser = app.login(Credentials.anonymous()) // Logs in with a new, different anonymous user val otherAnonUser = app.login(Credentials.anonymous(reuseExisting = false))
Correo electrónico/Contraseña
El proveedor de autenticación de correo electrónico/contraseña permite a los usuarios iniciar sesión en tu aplicación con un nombre de usuario de correo electrónico y una contraseña. Consulta Autenticación con correo electrónico/contraseña en la documentación de App Services para obtener más información.
Importante
Email/Password Users Require Registration
Email/password authentication requires that you register and then confirm the user-provided email and password before the user can authenticate to an App Services App. Learn how to register email/password users.
Para iniciar sesión con autenticación por correo electrónico/contraseña, crear una credencial por correo electrónico/contraseña llamando a Credentials.emailPassword() con el correo electrónico y la contraseña registrados del usuario, y luego pasar las credenciales generadas a aplicación.login():
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { val emailPasswordCredentials = Credentials.emailPassword(email, password) val user = app.login(emailPasswordCredentials) }
JWT personalizado
The Custom JWT authentication provider enables users to log in to your application with a custom JSON Web Token (JWT). Registration for JWT authentication is handled by the JWT provider. Refer to Custom JWT Authentication in the App Services documentation for more information.
Para iniciar sesión con autenticación JWT, cree una credencial JWT llamando a Credentials.jwt() con el JWT del usuario y luego pase la credencial generada a app.login():
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { // Registration is handled by the JWT provider val jwtCredentials = Credentials.jwt(jwtToken) val user = app.login(jwtCredentials) }
Llave API
El proveedor de autenticación de clave API permite que los usuarios autenticados no anónimos inicien sesión en tu aplicación con dicha clave. Consulte Autenticación con clave de API en la documentación de Servicios de aplicación para obtener más información.
Para iniciar sesión con autenticación de clave API, cree una credencial de clave API llamando a Credentials.apiKey() con la clave API del usuario y luego pasando la credencial generada a app.login():
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { val user = app.login(Credentials.apiKey(key)) }
User API keys are generated automatically and managed by the Kotlin SDK. Learn how to Manage User API Keys - Kotlin SDK.
Función personalizada
El proveedor de autenticación de función personalizada permite que los usuarios inicien sesión en tu aplicación utilizando lógica de autenticación personalizada gestionada por una Atlas Function. Consulta Autenticación de función personalizada en la documentación de App Services para más información.
To log in with Custom Function authentication, pass your custom arguments as a payload to Credentials.customFunction(), and then pass the generated credential to app.login():
// Create custom arguments for your Atlas Function val customCredentials = Credentials.customFunction( payload = mapOf("username" to "bob") ) val user = app.login(customCredentials)
Learn how to Call an Atlas Function - Kotlin SDK.
Nueva en la versión 1.9.0.
You can serialize data for a Custom Function credential using an EJSON encoder. For more information, including examples, refer to EJSON Encoding for Atlas.
El proveedor de autenticación de Google permite autenticar a los usuarios a través de su cuenta de Google existente mediante un 2.0 token OAuth.Consulta "Autenticación de Google" en la documentación de App Services para obtener más información.
Before you can authenticate users with Google, you must set up your application for Google User authentication:
In the Google Cloud Platform console, create an OAuth 2.0 client ID of type "Web application".
Configure your backend App to use that client ID and the associated client secret.
Enable OpenID Connect on the backend.
Utilice el Inicio de sesión de Google para Android oficial de Google para autenticar usuarios de Google en su aplicación de Android. El siguiente código implementa este flujo, comenzando con una llamada a un método a loginWithGoogle():
fun loginWithGoogle() { val gso = GoogleSignInOptions .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken("YOUR WEB APPLICATION CLIENT ID FOR GOOGLE AUTH") .build() val googleSignInClient = GoogleSignIn.getClient(activity, gso) val signInIntent: Intent = googleSignInClient.signInIntent val resultLauncher: ActivityResultLauncher<Intent> = // Note: this activity MUST inherit from ComponentActivity or AppCompatActivity to use this API registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> val task: Task<GoogleSignInAccount> = GoogleSignIn.getSignedInAccountFromIntent(result.data) handleSignInResult(task) } resultLauncher.launch(signInIntent) } fun handleSignInResult(completedTask: Task<GoogleSignInAccount>) { try { if (completedTask.isSuccessful) { val account: GoogleSignInAccount? = completedTask.getResult(ApiException::class.java) val token: String = account?.idToken!! val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { val user = app.login(Credentials.google(token, GoogleAuthType.ID_TOKEN)) } } else { Log.e("AUTH", "Google Auth failed: ${completedTask.exception}") } } catch (e: ApiException) { Log.e("AUTH", "Failed to authenticate using Google OAuth: " + e.message); } }
Tip
To learn more about Google Sign-In for Android, check out the official Google Sign-In for Android Integration Guide.
Kotlin Multiplatform (KMP) supports many environments, but this example shows sign-in on the Android platform. For information about signing into a Google account on Apple platforms, refer to the Swift SDK Example.
The Facebook authentication provider allows you to authenticate users through a Facebook app using their existing Facebook account. Refer to Facebook Authentication in the App Services documentation for more information.
Before you can authenticate users with Facebook, you must set up the authentication flow for your application by following the official Facebook Login for Android Quickstart.
In the login completion handler, get the logged in user's access token from the Facebook LoginResult. Use the access token to create a Facebook credential by calling Credentials.facebook() with the user's access token, and then pass the generated credential to app.login():
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID FacebookSdk.setApplicationId(YOUR_FACEBOOK_SDK_APP_ID) FacebookSdk.sdkInitialize(activity) val callbackManager = CallbackManager.Factory.create() LoginManager.getInstance().registerCallback( callbackManager, object : FacebookCallback<LoginResult> { override fun onSuccess(loginResult: LoginResult) { // Signed in successfully, forward credentials to MongoDB Realm. val accessToken = loginResult.accessToken runBlocking { val user = app.login(Credentials.facebook(accessToken.token)) } } override fun onCancel() { Log.v("AUTH", "Cancelled Facebook login") } override fun onError(exception: FacebookException) { Log.e("AUTH", "Failed to authenticate with Facebook: ${exception.message}") } })
Importante
Do Not Store Facebook Profile Picture URLs
Facebook profile picture URLs include the user's access token to grant permission to the image. To ensure security, do not store a URL that includes a user's access token. Instead, access the URL directly from the user's metadata fields when you need to fetch the image.
Kotlin Multiplatform (KMP) es compatible con muchos entornos, pero este ejemplo muestra cómo iniciar sesión en la plataforma Android. Para información sobre cómo iniciar sesión en una cuenta de Facebook en plataformas Apple, consulta el ejemplo del SDK de Swift.
Apple
El proveedor de autenticación Sign-in with Apple permite a los usuarios iniciar sesión en tu aplicación con un token personalizado proporcionado por Apple. Consulta Autenticación de Apple ID en la documentación de App Services para obtener más información.
Para iniciar sesión con la autenticación de Apple, cree una credencial de Apple llamando a Credentials.apple() con el token del usuario y luego pase la credencial generada a app.login():
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { // Registration is handled by Apple val appleCredentials = Credentials.apple(idToken) val user = app.login(appleCredentials) }
Kotlin Multiplatform (KMP) es compatible con muchos entornos, pero este ejemplo muestra cómo iniciar sesión en la plataforma Android. Para información sobre cómo iniciar sesión con Apple en las plataformas de Apple, ve el Swift SDK Ejemplo.
Retrieve Current User
Puede recuperar el usuario actualmente conectado con la propiedad App.currentUser:
val user = app.currentUser
Si varios usuarios han iniciado sesión en su aplicación, se devuelve el último usuario válido que inició sesión o null si no hay ningún usuario conectado. Consulte "Administrar aplicaciones multiusuario - SDK de Kotlin" para obtener más información.
Note that the currentUser object is persisted in local storage, so even if the app shuts down after the initial authentication, you do not need to call logIn again (unless the user has logged out or the user session has expired).
Use this method to log in offline or call an Atlas Function upon subsequent app opens.
Log In Offline
Cuando tu aplicación Realm autentica a un usuario, almacena en caché las credenciales del usuario. Puedes comprobar si existen credenciales de usuario para omitir el flujo de inicio de sesión y acceder al usuario almacenado en caché. Usa esto para abrir un realm sin conexión.
Nota
El inicio de sesión inicial requiere una conexión de red
Cuando un usuario se registra en tu aplicación o inicia sesión por primera vez con una cuenta existente en un cliente, este debe tener conexión de red. Comprobar las credenciales de usuario en caché permite abrir un reino sin conexión, pero solo si el usuario ha iniciado sesión previamente con conexión.
// You can only open a synced realm offline if there is a cached user credential. If // there is no app.currentUser, you must log them in, which requires a network connection. if (app.currentUser == null) { app.login(Credentials.emailPassword(email, password)) } // If the app.currentUser isn't null, you can use the cached credential to open the synced // realm even if the user is offline. val user = app.currentUser!! val realm = Realm.open(config) // Query the realm we opened, and see that it contains data val offlineToads: RealmResults<Toad> = realm.query<Toad>().find() Log.v("After opening a realm offline, offlineToads.size is ${offlineToads.size}") realm.close()
Manage User Tokens
El SDK de Realm Kotlin gestiona automáticamente los tokens de acceso, los actualiza cuando caducan e incluye un token de acceso válido para el usuario actual con cada solicitud. Los tokens se eliminan después de que el usuario cierra sesión.
Importante
Realm only refreshes a user's access token. Realm does not automatically refresh the refresh token. When the refresh token expires, the SDK can no longer get an updated access token and the device cannot sync until the user logs in again.
Para obtener más información sobre el acceso a la sesión de usuario y los tokens de actualización, consulte Sesiones de usuario en la documentación de App Services.
Obtener un token de acceso de usuario
Puede obtener el token de acceso actual de un usuario que haya iniciado sesión con la propiedad user.accessToken:
val token = user.accessToken
Si envía solicitudes fuera del SDK, debe incluir el token de acceso del usuario en cada solicitud y actualizarlo manualmente cuando caduque. Los tokens de acceso caducan 30 minutos después de que el usuario inicie sesión.
Puede obtener el token de actualización actual de un usuario que haya iniciado sesión con la propiedad user.refreshToken, que puede usar para solicitar un nuevo token de acceso:
// Gets the current refresh token for the user fun getRefreshToken(): String { return user.refreshToken }
Configurar la expiración del token de actualización
Refresh tokens expire after a set period of time. When the refresh token expires, the access token can no longer be refreshed and the user must log in again.
If the refresh token expires after the realm is open, the device will not be able to sync until the user logs in again. Your sync error handler should implement logic that catches a token expired error when attempting to sync, then redirect users to a login flow.
For information on configuring refresh token expiration, refer to Manage User Sessions in the App Services documentation.
Log a User Out
Advertencia
Cuando un usuario cierra su sesión, ya no puedes leer ni escribir datos en los realms sincronizados que haya abierto ese usuario. Como resultado, cualquier operación que no se haya completado antes de que el usuario que la inició cierre su sesión no podrá completarse correctamente y es probable que genere un error. Cualquier dato en una operación de escritura que falle de esta manera se perderá.
Puede cerrar la sesión de cualquier usuario, independientemente del proveedor de autenticación utilizado para iniciar sesión, utilizando user.logOut():
val app: App = App.create(YOUR_APP_ID) // Replace this with your App ID runBlocking { val user = app.login(credentials) // ... work with logged-in user ... // Ensure all local updates are uploaded // before logging out user.logOut() }
El método user.logOut():
Deletes locally stored user credentials from the device.
Immediately halts any synchronization to and from the user's realms.
Para usuarios anónimos, remueve el usuario.
Because logging out halts synchronization, you should only log out after all local Realm updates have uploaded to the server.
Observe Authentication Changes
New in version 10.8.0.
Se puede observar un flujo de eventos de cambio de autenticación llamando App.authenticationChangeAsFlow() . Este flujo emite eventos de AuthenticationChange en tres posibles estados, representados como subclases:
LoggedIn: A user logs into the app.LoggedOut: A a user logs out of the app.Removed: A user is removed from the app, which also logs them out.
These events contain a user property that provides a reference to the User object that has logged in, logged out, or been removed.
// Create a Flow of AuthenticationChange objects app.authenticationChangeAsFlow().collect { change: AuthenticationChange -> when (change) { is LoggedIn -> proceedToAppActivity(change.user) is LoggedOut -> proceedToLoginActivity(change.user) is Removed -> proceedToRemovedUserActivity(change.user) } }