Autenticar usuários - Java SDK
Nesta página
O Realm fornece uma API para autenticar usuários usando qualquer provedor de autenticação habilitado. Instancie um objeto Credentials
e passe-o para um dos métodos app.login()
ou app.loginAsync()
para autenticar um logon de usuário e criar um objeto User
. Cada provedor de autenticação corresponde a um método auxiliar estático utilizado para instanciar objeto Credentials
utilizando este provedor de autenticação.
Conecte-se
Você pode autenticar usuários com os métodos app.login()
ou app.loginAsync()
da instância do seu aplicativo da classe io.realm.mongodb.App
. Enquanto o método app.login()
bloqueia a execução do código no thread de chamada até que as credenciais fornecidas tenham sido bem-sucedidas ou não na autenticação de um usuário, o método app.loginAsync()
permite que a execução continue, lidando com o sucesso ou o fracasso com uma função de chamada de resposta que garante a execução na mesma thread que chamou app.loginAsync()
.
Se for bem-sucedido, o método app.login()
retornará um objeto User
. No evento de falha, o método app.login()
lança uma exceção do tipo ObjectServerError
.
Passe uma chamada de resposta para o método app.loginAsync()
para lidar com o sucesso ou a falha. Esta chamada de resposta aceita um único parâmetro do tipo App.Result
. O isSuccess()
método do App.Result
objeto passado para a chamada de resposta retorna um booleano que indica se a operação foi bem-sucedida. No evento de uma falha, você pode visualizar o erro que causou a falha usando o método getError()
.
Utilizador anónimo
Oprovedor de autenticação anônima do permite que os usuários façam login no seu aplicação com contas de curto prazo que não armazenam informações pessoais persistentes. Para fazer login com autenticação anônima, crie uma credencial anônima chamando Credentials.anonymous()
e, em seguida, passe a credencial gerada para app.login()
ou app.loginAsync()
.
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); Credentials anonymousCredentials = Credentials.anonymous(); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(anonymousCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated anonymously."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) val anonymousCredentials: Credentials = Credentials.anonymous() var user: User? app.loginAsync(anonymousCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated anonymously.") user = app.currentUser() } else { Log.e("AUTH", it.error.toString()) } }
Usuário de e-mail/senha
O fornecedor de autenticação por e-mail/senha permite que os usuários se conectam no seu aplicativo com um nome de usuário e uma senha de e-mail. Para fazer login com a autenticação de e-mail/senha, crie uma credencial de e-mail/senha ligando para Credentials.emailPassword()
com o e-mail e a senha do usuário. Em seguida, passe a credencial gerada para app.login()
ou app.loginAsync()
.
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); Credentials emailPasswordCredentials = Credentials.emailPassword("<email>", "<password>"); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(emailPasswordCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated using an email and password."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) val emailPasswordCredentials: Credentials = Credentials.emailPassword( "<email>", "<password>" ) var user: User? = null app.loginAsync(emailPasswordCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated using an email and password.") user = app.currentUser() } else { Log.e("AUTH", it.error.toString()) } }
Usuário da chave de API
O provedor de autenticação de chave de API permite que os usuários façam login em seu aplicativo com uma chave de API gerada automaticamente no SDK do cliente. Para fazer login com autenticação de chave API, crie uma credencial de chave API ligando para Credentials.apiKey()
com uma chave API. Em seguida, passe a credencial gerada para app.login()
ou app.loginAsync()
.
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); Credentials apiKeyCredentials = Credentials.apiKey("<key>"); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(apiKeyCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated using an API Key."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) val apiKeyCredentials: Credentials = Credentials.apiKey("<key>") var user: User? = null app.loginAsync(apiKeyCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated using an API Key.") user = app.currentUser() } else { Log.e("AUTH", "Error logging in: ${it.error.toString()}") } }
Usuário JWT personalizado
O fornecedor de autenticação de token JSON web personalizado permite que os usuários se conectem em seu aplicativo com um JSON web token personalizado. Para fazer login com a autenticação de token JSON web personalizado, crie uma credencial de token JSON web personalizado chamando Credentials.jwt()
com seu token JSON web personalizado. Em seguida, passe a credencial gerada para app.login()
ou app.loginAsync()
.
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); // fetch JWT from custom provider Credentials customJWTCredentials = Credentials.jwt("<token>"); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(customJWTCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated using a custom JWT."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) // fetch JWT from custom provider val customJWTCredentials: Credentials = Credentials.jwt("<token>") var user: User? = null app.loginAsync(customJWTCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated using a custom JWT.") user = app.currentUser() } else { Log.e("AUTH", "Error logging in: ${it.error.toString()}") } }
Usuário de função personalizada
O fornecedor de autenticação de função personalizada permite que os usuários façam login em seu aplicativo usando uma função de Realm definida em seu aplicativo. Para fazer login com autenticação de função personalizada, crie uma credencial ligando para Credentials.customFunction()
. O método customFunction() espera um documento que contenha as propriedades e valores utilizados pela função de autenticação Realm. Por exemplo, suponha que a função backend espere que o parâmetro de entrada inclua um campo denominado username
, assim:
exports = async function(loginPayload) { const { username } = loginPayload; ... }
O documento que você passa para Credentials.customFunction()
pode ter a seguinte aparência:
Document("username", "bob")
Em seguida, você passa a credencial gerada para app.login()
ou app.loginAsync()
.
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID).build()); Credentials customFunctionCredentials = Credentials.customFunction(new org.bson.Document("username", "bob")); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(customFunctionCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated using a custom function."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) val customFunctionCredentials: Credentials = Credentials.customFunction(org.bson.Document("username", "bob")) var user: User? = null app.loginAsync(customFunctionCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated using a custom function.") user = app.currentUser() } else { Log.e("AUTH", "Error logging in: ${it.error.toString()}") } }
Usuário do Facebook
O provedor de autenticação do Facebook permite que você autentique usuários por meio de um aplicativo do Facebook usando sua conta existente do Facebook.
Importante
Habilite o provedor de autenticação do Facebook
Para conectar um usuário com uma conta do Facebook existente, você deve configurar e habilitar o provedor de autenticação do Facebook para seu aplicativo.
Importante
Não armazene URLs de fotos de perfil do Facebook
Os URLs da imagem de perfil do Facebook incluem o token de acesso do usuário para conceder permissão à imagem. Para garantir a segurança, não armazene um URL que inclua um token de acesso do usuário. Em vez disso, acesse o URL diretamente dos campos de metadados do usuário quando precisar buscar a imagem.
Siga o início rápido oficial de login do Facebook para Android para configurar o fluxo de autenticação do seu aplicação. No manipulador de conclusão de login, obtenha o token de acesso do usuário conectado a partir do Facebook LoginResult. Use o token de acesso para criar uma credencial do Realm no Facebook e, em seguida, conectar o usuário ao seu aplicativo do Realm .
FacebookSdk.setApplicationId(YOUR_FACEBOOK_SDK_APP_ID); FacebookSdk.sdkInitialize(activity); CallbackManager callbackManager = CallbackManager.Factory.create(); LoginManager.getInstance().registerCallback(callbackManager, new FacebookCallback<LoginResult>() { public void onSuccess(LoginResult loginResult) { // Signed in successfully, forward credentials to MongoDB Realm. AccessToken accessToken = loginResult.getAccessToken(); Credentials facebookCredentials = Credentials.facebook(accessToken.getToken()); app.loginAsync(facebookCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully logged in to MongoDB Realm using Facebook OAuth."); } else { Log.e("AUTH", "Failed to log in to MongoDB Realm", it.getError()); } }); } public void onCancel() { Log.v("AUTH", "Facebook authentication cancelled."); } public void onError(FacebookException exception) { Log.e("AUTH", "Failed to authenticate using Facebook: " + exception.getMessage()); } } ); LoginManager.getInstance().logIn(activity, null);
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 val facebookCredentials: Credentials = Credentials.facebook(accessToken.token) app.loginAsync(facebookCredentials) { if (it.isSuccess) { Log.v( "AUTH", "Successfully logged in to MongoDB Realm using Facebook OAuth." ) } else { Log.e("AUTH", "Failed to log in to MongoDB Realm", it.error) } } } override fun onCancel() { Log.v("AUTH", "Cancelled Facebook login") } override fun onError(exception: FacebookException) { Log.e("AUTH", "Failed to authenticate with Facebook: ${exception.message}") } })
Usuário do Google
Importante
Para fazer login de um usuário com sua Conta do Google existente, você deve configurar e ativar o provedor de autenticação do Google para seu aplicativo.
Para configurar seu aplicativo para autenticação de usuário do Google:
No console do Google Cloud Platform, crie um OAuth 2.0 ID do cliente do tipo "aplicativo Web".
Configure seu aplicativo de backend para usar esse ID de cliente e o segredo de cliente associado.
Habilite o OpenID Connect no backend.
Use o login oficial do Google para Android para autenticar usuários do Google em seu aplicativo Android:
Observação
Exemplo de código abaixo
Para uma implementação destas instruções, confira o bloco de código abaixo.
Adicione a dependência do Google Sign-In para Android ao bloco
dependencies
do seu nível de aplicativobuild.gradle
:com.google.android.gms:play-services-auth:19.2.0 Criar um GoogleSignInOptions com as seguintes opções de construtor:
uma solicitação de token de ID -- passe seu OAuth 2.0 ID do cliente como
serverClientId
.
Utilize o
GoogleSignInOptions
para criar umGoogleSignInClient
com GoogleSignIn.getClient()Use o
GoogleSignInClient
para criar umIntent
capaz de acionar o Login do Google.Usar registrarForActivityResult() para configurar um retorno de chamada. Sua chamada de resposta deve usar GoogleSignIn.getSignedInAccountFromIntent() para acessar o resultado do Google Sign-In: a
Task<GoogleSignInAccount>
.Use o lançamento () método do ActivityResultLauncher retornado na etapa anterior para iniciar o Google Sign-In. Passe o método
launch()
seuIntent
login do Google.Use
isSuccessful()
para lidar com erros de login do Google.Acesse o resultado da tarefa (um GoogleSignInAccount) com
getResult()
.Acesse o token de ID para o
GoogleSignInAccount
comgetIdToken()
.Crie um objeto de Realm
Credentials
com Credentials.google(). Passe o token de ID como o primeiro parâmetro e GoogleAuthType.ID_TOKEN como o segundo parâmetro.Use os métodos app.loginAsync() ou app.login() para se autenticar com o backend do Atlas App Services usando o token.
O seguinte código implementa esse fluxo, começando com uma chamada de método para loginWithGoogle()
:
private void signInWithGoogle() { GoogleSignInOptions gso = new GoogleSignInOptions .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken("YOUR WEB APPLICATION CLIENT ID FOR GOOGLE AUTH") .build(); GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, gso); Intent signInIntent = googleSignInClient.getSignInIntent(); ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { public void onActivityResult(ActivityResult result) { Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(result.getData()); handleSignInResult(task); } }); resultLauncher.launch(signInIntent); } private void handleSignInResult(Task<GoogleSignInAccount> completedTask) { try { if (completedTask.isSuccessful()) { GoogleSignInAccount account = completedTask.getResult(ApiException.class); String token = account.getIdToken(); Credentials googleCredentials = Credentials.google(token, GoogleAuthType.ID_TOKEN); app.loginAsync(googleCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully logged in to MongoDB Realm using Google OAuth."); } else { Log.e("AUTH", "Failed to log in to MongoDB Realm: ", it.getError()); } }); } else { Log.e("AUTH", "Google Auth failed: " + completedTask.getException().toString()); } } catch (ApiException e) { Log.w("AUTH", "Failed to log in with Google OAuth: " + e.getMessage()); } }
fun loginWithGoogle() { val gso = GoogleSignInOptions .Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestIdToken("YOUR WEB APPLICATION CLIENT ID FOR GOOGLE AUTH") .build() val googleSignInClient = GoogleSignIn.getClient(this, gso) val signInIntent: Intent = googleSignInClient.signInIntent val resultLauncher: ActivityResultLauncher<Intent> = 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 googleCredentials: Credentials = Credentials.google(token, GoogleAuthType.ID_TOKEN) app.loginAsync(googleCredentials) { if (it.isSuccess) { Log.v( "AUTH", "Successfully logged in to MongoDB Realm using Google OAuth." ) } else { Log.e("AUTH", "Failed to log in to MongoDB Realm", it.error) } } } else { Log.e("AUTH", "Google Auth failed: ${completedTask.exception}") } } catch (e: ApiException) { Log.e("AUTH", "Failed to authenticate using Google OAuth: " + e.message); } }
Dica
Veja também:
Para saber mais sobre o Google Sign-In para Android, confira o Guia de Integração oficial do Google Sign-In para Android.
Usuário da Apple
O acesso com o fornecedor de autenticação da Apple permite que os usuários se conectem em seu aplicativo com um token personalizado fornecido pela Apple. Para fazer login com a autenticação Sign-in with Apple, crie uma credencial Sign-in with Apple chamando Credentials.apple()
com o token fornecido pela Apple. Em seguida, passe a credencial gerada para app.login()
ou app.loginAsync()
.
String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); // fetch apple token using Apple SDK Credentials appleCredentials = Credentials.apple("<token>"); AtomicReference<User> user = new AtomicReference<User>(); app.loginAsync(appleCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated using Sign-in with Apple."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } });
val appID = YOUR_APP_ID // replace this with your App ID val app: App = App( AppConfiguration.Builder(appID) .build() ) // fetch IDToken using Apple SDK val appleCredentials: Credentials = Credentials.apple("<token>") var user: User? = null app.loginAsync(appleCredentials) { if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated using Sign-in with Apple.") user = app.currentUser() } else { Log.e("AUTH", "Error logging in: ${it.error.toString()}") } }
Dica
Se você receber uma mensagem de erro Login failed
dizendo que o token contains
an invalid number of segments
, verifique se está passando uma versão de string codificada em UTF-8 do JWT.
Login off-line
O App Services managed sessões com tokens de acesso e atualizam tokens. Os SDKs do cliente fornecem a lógica para managed tokens e fornecem solicitações.
O SDK armazena estes tokens em preferências compartilhadas.
Quando seu aplicativo Realm autentica um usuário, armazena em cache as credenciais do usuário. Você pode verificar as credenciais de usuário existentes para ignorar o fluxo de login e acessar o usuário em cache. Use isto para abrir um realm offline.
Observação
O login inicial exige uma conexão de rede
Quando um usuário se inscreve em seu aplicativo ou faz login pela primeira vez com uma conta existente em um cliente, o cliente deve ter uma conexão de rede. A verificação de credenciais de usuário em cache permite que você abra um domínio offline, mas somente se o usuário já tiver feito login enquanto estiver online.
// Log the user into the backend app. // The first time you login, the user must have a network connection. String appID = YOUR_APP_ID; // replace this with your App ID App app = new App(new AppConfiguration.Builder(appID) .build()); // Check for an existing user. // If the user is offline but credentials are // cached, this returns the existing user. AtomicReference<User> user = new AtomicReference<User>(); user.set(app.currentUser()); if (user.get() == null) { // If the device has no cached user // credentials, log them in. Credentials anonymousCredentials = Credentials.anonymous(); app.loginAsync(anonymousCredentials, it -> { if (it.isSuccess()) { Log.v("AUTH", "Successfully authenticated anonymously."); user.set(app.currentUser()); } else { Log.e("AUTH", it.getError().toString()); } }); }
// Log the user into the backend app. // The first time you login, the user must have a network connection. val appID = YOUR_APP_ID // replace this with your App ID val app = App( AppConfiguration.Builder(appID) .build() ) // Check for an existing user. // If the user is offline but credentials are // cached, this returns the existing user. val user = AtomicReference<User?>() user.set(app.currentUser()) if (user.get() == null) { // If the device has no cached user // credentials, log them in. val anonymousCredentials = Credentials.anonymous() app.loginAsync( anonymousCredentials ) { it: App.Result<User?> -> if (it.isSuccess) { Log.v("AUTH", "Successfully authenticated anonymously.") user.set(app.currentUser()) } else { Log.e("AUTH", it.error.toString()) } } }
Obtenha um token de acesso do usuário
Quando um usuário se conecta, o Atlas App Services cria um token de acesso para o usuário que lhe concede acesso à sua aplicação. O Realm SDK gerencia automaticamente os tokens de acesso, atualiza-os quando expiram e inclui um token de acesso válido para o usuário atual em cada solicitação. O Realm não atualiza automaticamente o token de atualização. Quando o token de atualização expira, o usuário deve se conectar novamente.
Se você enviar solicitações fora do SDK, precisará incluir o token de acesso do usuário em cada solicitação e atualizar manualmente o token quando ele expirar.
Você pode acessar e atualizar um token de acesso de usuário conectado ao SDK a partir de seu objeto Realm.User
, como no seguinte exemplo:
// Gets a valid user access token to authenticate requests public String getValidAccessToken(User user) { // An already logged in user's access token might be stale. To // guarantee that the token is valid, refresh it if necessary. user.refreshCustomData(); return user.getAccessToken(); }
// Gets a valid user access token to authenticate requests fun getValidAccessToken(user: User?): String { // An already logged in user's access token might be stale. To // guarantee that the token is valid, refresh it if necessary. user!!.refreshCustomData() return user.accessToken }
Desconectar um usuário
Você pode desconectar qualquer usuário, independentemente do provedor de autenticação usado para se conectar, usando os métodos user.logOut()
ou user.logOutAsync()
. Ambos os métodos:
excluir credenciais de usuário armazenadas localmente do dispositivo
interromper imediatamente qualquer sincronização de e para os domínios do usuário
Como o encerramento da sessão interrompe a sincronização, você só deve sair depois que todas as atualizações locais do Realm tiverem sido enviadas para o servidor.
user.get().logOutAsync( result -> { if (result.isSuccess()) { Log.v("AUTH", "Successfully logged out."); } else { Log.e("AUTH", result.getError().toString()); } });
user?.logOutAsync { if (it.isSuccess) { Log.v("AUTH", "Successfully logged out.") } else { Log.e("AUTH", it.error.toString()) } }