Skip to content

(DOCSP-39526): Consolidate Authenticate Users page #3281

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/bluehawk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ jobs:
- uses: actions/checkout@v3
- uses: actions/setup-node@v1
with:
node-version: 15.x
node-version: 18.x
- run: npx bluehawk check -i "*.md" -i "*.properties" -i "*.lock" examples tutorial
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You can get the current user with ``app::get_current_user()``:
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
To log in with a Google authentication code, pass a Google authentication code to
:cpp-sdk:`credentials::google_auth_code() <structrealm_1_1App_1_1credentials.html>`.

.. literalinclude:: /examples/generated/cpp/authentication.snippet.google-auth-code.cpp
:language: cpp

To log in with a Google ID token, pass a Google ID token to
:cpp-sdk:`credentials::google_id_token() <structrealm_1_1App_1_1credentials.html>`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
To authenticate and log users in to your :cpp-sdk:`App
<classrealm_1_1App.html>`, first instantiate a
:cpp-sdk:`credentials <structrealm_1_1App_1_1credentials.html>`
object containing the credentials associated with the authentication provider.
Then, pass it to the ``login()`` function.

Each authentication provider corresponds to a :cpp-sdk:`static function
<structrealm_1_1App_1_1credentials.html>`
used to instantiate ``credentials`` objects for that authentication provider.

If successful, ``app::login()`` returns a :cpp-sdk:`user
<structrealm_1_1user.html>` object. In the event of a failure,
``app::login()`` throws an exception of type :cpp-sdk:`app_error
<structrealm_1_1app__error.html>`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
C++ does not provide a dedicated API to observe authentication changes. However,
you can check the user's :cpp-sdk:`state
<structrealm_1_1user.html#a51821add445bf8da874b2532c1010b5a>`, which is
an enum whose possible values are:

- ``logged_out``
- ``logged_in``
- ``removed``
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
When a user registers or successfully authenticates to your App, Atlas App
Services automatically creates a :cpp-sdk:`user
<structrealm_1_1user.html>` object, which contains a unique
identifier and user state information. You can optionally configure
:ref:`custom user data <sdks-custom-user-data>` if your app needs to store
additional user data. To learn more about the user object that App Services
provides, refer to :ref:`<user-objects>` in the App Services documentation.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
You can call :cpp-sdk:`.refresh_custom_user_data()
<structrealm_1_1user.html#a6e08623890de4003a00a351e939a0a9f>`
on a logged-in user to refresh the user's auth session. Then, get the
:cpp-sdk:`.access_token() <structrealm_1_1user.html#ac059073ce64f125553e5bd395bd17cd6>`
as a string you can use in your code. You might use code similar to this to
fetch an access token:
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
You can call :cpp-sdk:`.refresh_custom_user_data()
<structrealm_1_1user.html#a6e08623890de4003a00a351e939a0a9f>`
on a logged-in user to refresh the user's auth session.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Once you have an authenticated user, you can retrieve the User object with the
:dotnet-sdk:`App.CurrentUser <reference/Realms.Sync.App.html#Realms_Sync_App_CurrentUser>`
property.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
To authenticate and log users in to your :dotnet-sdk:`App
<reference/Realms.Sync.App.html>`, first instantiate a
:dotnet-sdk:`Credentials <reference/Realms.Sync.Credentials.html>`
object containing the credentials associated with the authentication provider.
Then, pass it to :dotnet-sdk:`LogInAsync()
<reference/Realms.Sync.App.html#Realms_Sync_App_LogInAsync_Realms_Sync_Credentials_>`.

Each authentication provider corresponds to a :dotnet-sdk:`factory method
<reference/Realms.Sync.Credentials.html>`
used to instantiate ``Credentials`` objects for that authentication provider.

If successful, ``LogInAsync()`` returns a :dotnet-sdk:`User
<reference/Realms.Sync.User.html>` object. In the event of a failure,
``LogInAsync()`` throws an exception of type :dotnet-sdk:`AppException
<reference/Realms.Sync.Exceptions.AppException.html>`.

.. tip::

You can get the authentication provider type used to log in a user
through the :dotnet-sdk:`UserIdentity.Provider
<reference/Realms.Sync.UserIdentity.html#Realms_Sync_UserIdentity_Provider>`
property. If the user is currently logged out, the most recent provider
used to log in the user is returned.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Once logged in, you can log out by calling the ``LogOutAsync()`` method:
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.. versionadded:: v11.6.0

You can observe a flow of authentication change events by calling
:dotnet-sdk:`User.Changed() <reference/Realms.Sync.User.html#Realms_Sync_User_Changed>`
on a valid user object.

Currently, ``User.Changed()`` triggers on all user events and you should add a
handler to ensure your responses to events are idempotent.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
When a user registers or successfully authenticates to your App, Atlas App
Services automatically creates a :dotnet-sdk:`User
<reference/Realms.Sync.User.html>` object, which contains a unique
identifier and provider-specific :ref:`user metadata <sdks-user-metadata>`.
You can optionally configure :ref:`custom user data <sdks-custom-user-data>`
if your app needs to store additional user data. To learn more about the
user object that App Services provides, refer to :ref:`<user-objects>` in the
App Services documentation.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
To log in with anonymous
authentication, create an anonymous credential by calling
:flutter-sdk:`Credentials.anonymous() <realm/Credentials/Credentials.anonymous.html>`
and then pass the generated credential to
``app.logIn``.

.. literalinclude:: /examples/generated/flutter/authenticate_users_test.snippet.anonymous-credentials.dart
:language: dart

If you want more than one anonymous user, set ``reuseCredentials: false``
when creating additional anonymous credentials.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To log in with API key authentication, create an :flutter-sdk:`ApiKey <realm/ApiKey-class.html>`
credential by calling :flutter-sdk:`Credentials.apiKey() <realm/Credentials/Credentials.apiKey.html>`
on an API key string. Then pass the credential to ``app.logIn()``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To log in with Apple authentication, pass an Apple access token to
:flutter-sdk:`Credentials.apple() <realm/Credentials/Credentials.apple.html>`.
Then pass the credential to ``app.logIn``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To log in with Custom Function authentication, pass a stringified JSON with
your custom arguments to :flutter-sdk:`Credentials.function() <realm/Credentials/Credentials.function.html>`.
Then pass the credential to ``app.logIn``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To log in with Custom JWT authentication, create a JWT credential by calling
:flutter-sdk:`Credentials.jwt() <realm/Credentials/Credentials.jwt.html>`
on a JWT string. Then pass the credential to ``app.logIn``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To log in with email/password authentication, create an
email/password credential by calling :flutter-sdk:`Credentials.emailPassword() <realm/Credentials/Credentials.emailPassword.html>`
with the user's email and password.
Then pass the credential to ``app.logIn``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
To log in with Facebook authentication, pass a Facebook access token to
:flutter-sdk:`Credentials.facebook() <realm/Credentials/Credentials.facebook.html>`.
Then pass the credential to ``app.logIn``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Once you have an authenticated user, you can retrieve the User object with the
:flutter-sdk:`App.currentUser <realm/App/currentUser.html>`
property.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
To log in with a Google authentication code, pass a Google authentication code to
:flutter-sdk:`Credentials.googleAuthCode() <realm/Credentials/Credentials.googleAuthCode.html>`.
Then pass the credential to ``app.logIn``.

.. literalinclude:: /examples/generated/flutter/authenticate_users_test.snippet.google-auth-code-credentials.dart
:language: dart

To log in with a Google ID token, pass a Google ID token to
:flutter-sdk:`Credentials.googleIdToken() <realm/Credentials/Credentials.googleIdToken.html>`.
Then pass the credential to ``app.logIn``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
To authenticate and log users in to your :flutter-sdk:`App
<realm/App-class.html>`, first instantiate a
:flutter-sdk:`Credentials <realm/Credentials-class.html>`
object containing the credentials associated with the authentication provider.
Then, pass it to :flutter-sdk:`App.logIn() <realm/App/logIn.html>`.

Each authentication provider corresponds to a :flutter-sdk:`Credentials
constructor <realm/Credentials-class.html>` used to instantiate ``Credentials``
objects for that authentication provider.

If successful, ``App.logIn()`` returns a :flutter-sdk:`User
<realm/User-class.html>` object. In the event of a failure, ``App.logIn()``
throws an exception of type :flutter-sdk:`AppException
<realm/AppException-class.html>`.

.. tip::

You can get the authentication provider type used to log in a user
through the :flutter-sdk:`UserIdentity.provider
<realm/UserIdentity-class.html>` property. If the user is currently logged
out, the most recent provider used to log in the user is returned.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
You can log out any user, regardless of the authentication provider used
to log in, using :flutter-sdk:`User.logOut() <realm/User/logOut.html>`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Dart does not provide a dedicated API to observe authentication changes. However,
you can check the user's :flutter-sdk:`state
<realm/User/state.html>`, whose value is an enum of type
:flutter-sdk:`UserState <realm/UserState.html>`. This can give you information
about whether the user is logged in, logged out, or removed from the device.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
When a user registers or successfully authenticates to your App, Atlas App
Services automatically creates a :flutter-sdk:`User
<realm/User-class.html>` object, which contains a unique
identifier and provider-specific :ref:`user metadata <sdks-user-metadata>`.
You can optionally configure :ref:`custom user data <sdks-custom-user-data>`
if your app needs to store additional user data. To learn more about the
user object that App Services provides, refer to :ref:`<user-objects>` in the
App Services documentation.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
You can get the access token with the :flutter-sdk:`User.accessToken
<realm/User/accessToken.html>` property.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Refresh an access token with :flutter-sdk:`User.refreshCustomData() <realm/User/refreshCustomData.html>`.

.. literalinclude:: /examples/generated/flutter/access_token_test.snippet.refresh-access-token.dart
:language: dart

You can also periodically refresh the access token
with `Timer.periodic() <https://api.flutter.dev/flutter/dart-async/Timer-class.html>`__
from the ``dart:async`` library. Wrap the call to ``User.refreshCustomData()``
with the timer's callback function.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To log in with anonymous
authentication, create an anonymous credential by calling
``Credentials.anonymous()`` and then pass the generated credential to
``app.login()`` or ``app.loginAsync()``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To log in with API Key authentication, create an
API Key credential by calling ``Credentials.apiKey()``
with an API Key. Then pass the generated credential
to ``app.login()`` or ``app.loginAsync()``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To log in with Sign-in with Apple authentication, create a
Sign-in with Apple credential by calling ``Credentials.apple()``
with the token provided by Apple. Then pass the generated credential
to ``app.login()`` or ``app.loginAsync()``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
To log in with custom function authentication, create a credential by calling
``Credentials.customFunction()``. The :java-sdk:`customFunction()
<io/realm/mongodb/Credentials.html#customFunction-Document->` method expects a
Document that contains the properties and values used by the Atlas auth function.
For example, suppose the backend function expects the input parameter to include
a field named ``username``, like this:

.. code-block:: js
:copyable: false

exports = async function(loginPayload) {
const { username } = loginPayload;
...
}

The document you pass to ``Credentials.customFunction()`` might look like this:

.. code-block:: java
:copyable: false

Document("username", "bob")

You then pass the generated credential to ``app.login()`` or ``app.loginAsync()``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To log in with custom JWT authentication, create a
custom JWT credential by calling ``Credentials.jwt()``
with your custom JWT. Then pass the generated credential
to ``app.login()`` or ``app.loginAsync()``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
To log in with email/password authentication, create an
email/password credential by calling ``Credentials.emailPassword()``
with the user's email and password. Then pass the generated credential
to ``app.login()`` or ``app.loginAsync()``.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Follow the official :facebook:`Facebook Login for Android Quickstart
<docs/facebook-login/android>` to set up the authentication flow for your
application. In the login completion handler, get the logged in user's access
token from the Facebook :facebook:`LoginResult
<docs/reference/android/current/class/LoginResult>`. Use the access token to
create a Facebook credential for Atlas Device SDK, and then log the user into
your app.
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
Use Google's official :google:`Sign-In for Android <identity/sign-in/android>` to authenticate Google
users in your Android application:

.. note:: Code Example Below

For an implementation of these instructions, check out the code block
below.

1. Add the Google Sign-In for Android dependency to the ``dependencies``
block of your application level ``build.gradle``:

.. code-block:: groovy
:copyable: false

com.google.android.gms:play-services-auth:19.2.0

#. Create a :google:`GoogleSignInOptions
<android/reference/com/google/android/gms/auth/api/signin/GoogleSignInOptions>`
with the following builder options:

- :google:`default sign in
<android/reference/com/google/android/gms/auth/api/signin/GoogleSignInOptions.Builder#public-builder-googlesigninoptions-googlesigninoptions>`
- an :google:`ID token request
<android/reference/com/google/android/gms/auth/api/signin/GoogleSignInOptions.Builder#public-googlesigninoptions.builder-requestidtoken-string-serverclientid>`
-- pass your OAuth 2.0 client ID as the ``serverClientId``.

#. Use the ``GoogleSignInOptions`` to create a ``GoogleSignInClient``
with :google:`GoogleSignIn.getClient()
<android/reference/com/google/android/gms/auth/api/signin/GoogleSignIn#getClient(android.content.Context,%20com.google.android.gms.auth.api.signin.GoogleSignInOptions)>`

#. Use the ``GoogleSignInClient`` to create an ``Intent`` capable of
triggering Google Sign-In.

#. Use :android:`registerForActivityResult()
<reference/androidx/activity/result/ActivityResultCaller#registerForActivityResult(androidx.activity.result.contract.ActivityResultContract%3CI,O%3E,androidx.activity.result.ActivityResultCallback%3CO%3E)>`
to configure a callback. Your callback should use :google:`GoogleSignIn.getSignedInAccountFromIntent()
<android/reference/com/google/android/gms/auth/api/signin/GoogleSignIn#getSignedInAccountFromIntent(android.content.Intent)>`
to access the result of Google Sign-In: a ``Task<GoogleSignInAccount>``.

#. Use the :android:`launch()
<reference/androidx/activity/result/ActivityResultLauncher#launch(I)>`
method of the :android:`ActivityResultLauncher
<reference/androidx/activity/result/ActivityResultLauncher>`
returned in the previous step to start Google Sign-In. Pass the
``launch()`` method your Google Sign-In ``Intent``.

#. Use ``isSuccessful()`` to handle Google Sign-In errors.

#. Access the result of the task (a :google:`GoogleSignInAccount
<android/reference/com/google/android/gms/auth/api/signin/GoogleSignInAccount>`)
with ``getResult()``.

#. Access the ID token for the ``GoogleSignInAccount`` with ``getIdToken()``.

#. Create a Realm ``Credentials`` object with :java-sdk:`Credentials.google()
<io/realm/mongodb/Credentials.html#google-java.lang.String-io.realm.mongodb.auth.GoogleAuthType->`.
Pass the ID token as the first parameter, and :java-sdk:`GoogleAuthType.ID_TOKEN
<io/realm/mongodb/auth/GoogleAuthType.html#ID_TOKEN>` as the second parameter.

#. Use the :java-sdk:`app.loginAsync()
<io/realm/mongodb/App.html#loginAsync-io.realm.mongodb.Credentials-io.realm.mongodb.App.Callback->`
or :java-sdk:`app.login() <io/realm/mongodb/App.html#login-io.realm.mongodb.Credentials->`
methods to authenticate with the Atlas App Services backend using the token.

.. seealso::

To learn more about Google Sign-In for Android, check out the
official :google:`Google Sign-In for Android Integration Guide
<identity/sign-in/android/start-integrating>`.

The following code implements this flow, starting with a method call to
``loginWithGoogle()``:
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
To authenticate and log users in to your :java-sdk:`App
<io/realm/mongodb/App.html>`, first instantiate a
:java-sdk:`Credentials <io/realm/mongodb/Credentials.html>` object containing
the credentials associated with the authentication provider.
Then, pass it to :java-sdk:`App.login()
<io/realm/mongodb/App.html#login(io.realm.mongodb.Credentials)>` or
:java-sdk:`App.loginAsync() <io/realm/mongodb/App.html#loginAsync(io.realm.mongodb.Credentials,io.realm.mongodb.App.Callback)>`.

While the ``app.login()`` method blocks
code execution in the calling thread until the supplied credentials have
either succeeded or failed to authenticate a user, the
``app.loginAsync()`` method allows execution to continue, handling
success or failure with a callback function that is guaranteed to
execute on the same thread that called ``app.loginAsync()``.

Each authentication provider corresponds to a :java-sdk:`static helper method
<io/realm/mongodb/Credentials.html>` used to instantiate ``Credentials``
objects for that authentication provider.

If successful, ``App.login()`` returns a :java-sdk:`User <io/realm/mongodb/User.html>`
object. In the event of a failure, ``App.login()`` throws an
exception of type :java-sdk:`AppException <io/realm/mongodb/AppException.html>`.

Pass a callback to the ``App.loginAsync()`` method to handle success or
failure. This callback accepts a single parameter of type
``App.Result``. The ``isSuccess()`` method of the ``App.Result`` object
passed to the callback returns a boolean that indicates whether the
operation succeeded. In the event of a failure, you can view the
error that caused the failure using the ``getError()`` method.

.. tip::

You can get the authentication provider type used to log in a user
through the :java-sdk:`UserIdentity.getProvider()
<io/realm/mongodb/UserIdentity.html>` method. If the user is currently
logged out, the most recent provider used to log in the user is returned.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
You can log out any user, regardless of the authentication provider used
to log in, using the ``user.logOut()`` or ``user.logOutAsync()``
methods.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
When a user registers or successfully authenticates to your App, Atlas App
Services automatically creates a :java-sdk:`User
<io/realm/mongodb/User.html>` object, which contains a unique
identifier and provider-specific :ref:`user metadata <sdks-user-metadata>`.
You can optionally configure :ref:`custom user data <sdks-custom-user-data>`
if your app needs to store additional user data. To learn more about the
user object that App Services provides, refer to :ref:`<user-objects>` in the
App Services documentation.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
To log in, create an anonymous credential and pass it to ``App.logIn()``:
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
To log in with an API key, create an API Key credential with a server or user
API key and pass it to ``App.logIn()``:
Loading
Loading