对用户进行身份验证 - Web SDK
Overview
Web SDK 为开发者提供统一的 API,以便为任何身份验证提供者的应用程序用户进行身份验证。用户通过为给定的身份验证提供者提供身份验证凭证来登录,SDK 会自动管理身份验证令牌并刷新登录用户的数据。
登录
匿名
匿名提供商允许用户使用没有关联信息的临时帐户登录您的应用程序。
要进行登录,请创建一个匿名凭证并将其传递给App.logIn()
async function loginAnonymous() { // Create an anonymous credential const credentials = Realm.Credentials.anonymous(); // Authenticate the user const user = await app.logIn(credentials); // `App.currentUser` updates to match the logged in user console.assert(user.id === app.currentUser.id); return user; } const user = await loginAnonymous();
电子邮件/密码
电子邮件/密码身份验证提供者允许用户使用电子邮件地址和密码登录您的应用程序。
要进行登录,请使用用户的电子邮件地址和密码创建电子邮件/密码档案并将其传递给 App.logIn()
:
async function loginEmailPassword(email, password) { // Create an email/password credential const credentials = Realm.Credentials.emailPassword(email, password); // Authenticate the user const user = await app.logIn(credentials); // `App.currentUser` updates to match the logged in user console.assert(user.id === app.currentUser.id); return user; } const user = await loginEmailPassword("joe.jasper@example.com", "passw0rd");
API 密钥
API 密钥身份验证提供者允许服务器进程直接或代表用户访问您的应用程序。
要使用 API 密钥进行登录,请使用服务器或用户 API 密钥创建一个 API 密钥档案并将其传递给 App.logIn()
:
async function loginApiKey(apiKey) { // Create an API Key credential const credentials = Realm.Credentials.apiKey(apiKey); // Authenticate the user const user = await app.logIn(credentials); // `App.currentUser` updates to match the logged in user console.assert(user.id === app.currentUser.id); return user; } const user = await loginApiKey(REALM_API_KEY.key); // add previously generated API key
自定义函数
自定义函数身份验证提供者允许您通过运行接收有关用户的任意信息有效负载的函数来处理用户身份验证。
要通过自定义函数提供者进行登录,请创建具有负荷对象的自定义函数档案并将其传递给 App.logIn()
:
async function loginCustomFunction(payload) { // Create a Custom Function credential const credentials = Realm.Credentials.function(payload); // Authenticate the user const user = await app.logIn(credentials); // `App.currentUser` updates to match the logged in user console.assert(user.id === app.currentUser.id); return user; } const user = await loginCustomFunction({ username: "ilovemongodb" });
自定义 JWT
自定义 JSON Web 令牌身份验证提供程序允许您使用任何返回JSON web token的身份验证系统处理用户身份验证。
要进行登录,请使用外部系统中的 JWT 创建自定义 JWT 档案并将其传递给 App.logIn()
:
async function loginCustomJwt(jwt) { // Create a Custom JWT credential const credentials = Realm.Credentials.jwt(jwt); // Authenticate the user const user = await app.logIn(credentials); // `App.currentUser` updates to match the logged in user console.assert(user.id === app.currentUser.id); return user; } const user = await loginCustomJwt("eyJ0eXAi...Q3NJmnU8oP3YkZ8");
Facebook 身份验证
Facebook身份验证提供者允许您使用用户现有的 Facebook 帐户通过 Facebook 应用对用户进行身份验证。 您可以使用内置身份验证流程或使用 Facebook SDK 进行身份验证。
重要
请勿存储 Facebook 个人资料图片的 URL
Facebook 个人资料图片 URL 包含用户的访问令牌,用于授予该图像的权限。为了确保安全,请勿存储包含用户访问令牌的 URL。相反,在需要获取图像时,可直接从用户的元数据字段访问 URL。
使用内置 Facebook OAuth 2.0 流程
Realm Web SDK 包含处理 OAuth 2.0 流程的方法,并且您无需安装 Facebook SDK。内置流程将遵循以下三个主要步骤:
通过 Facebook 档案调用
app.logIn()
。档案必须指定您的应用的 URL,该 URL 也作为重定向 URI 列出在提供者配置中。// The redirect URI should be on the same domain as this app and // specified in the auth provider configuration. const redirectUri = "https://app.example.com/handleOAuthLogin"; const credentials = Realm.Credentials.facebook(redirectUri); // Calling logIn() opens a Facebook authentication screen in a new window. const user = await app.logIn(credentials); // The app.logIn() promise will not resolve until you call `Realm.handleAuthRedirect()` // from the new window after the user has successfully authenticated. console.log(`Logged in with id: ${user.id}`); 一个新窗口打开并显示 Facebook 身份验证屏幕,用户在该窗口中对您的应用程序进行身份验证和授权。完成后,新窗口将重定向到凭证中指定的 URL。
您在重定向的页面上调用
Realm.handleAuthRedirect()
,该页面将存储用户的 Atlas App Services 访问令牌并关闭窗口。原始应用窗口将自动检测访问令牌并结束用户登录流程。// When the user is redirected back to your app, handle the redirect to // save the user's access token and close the redirect window. This // returns focus to the original application window and automatically // logs the user in. Realm.handleAuthRedirect();
使用 Facebook SDK 进行身份验证
您可以使用 官方Facebook SDK 处理用户身份验证和重定向流程。完成身份验证后, Facebook SDK 会返回一个访问权限令牌,您可以使用该令牌结束用户登录到您应用的流程。
// Get the access token from the Facebook SDK const { accessToken } = FB.getAuthResponse(); // Define credentials with the access token from the Facebook SDK const credentials = Realm.Credentials.facebook(accessToken); // Log the user in to your app await app.logIn(credentials);
Google 身份验证
Google身份验证提供程序允许您使用用户现有的 Google 帐户通过 Google 项目对用户进行身份验证。
将 Google 用户登录到您的应用分为以下两个步骤:
首先,您需要通过 Google 对用户进行身份验证。 您可以使用 Google One Tap 等库 获得简化的体验。
其次,可以使用 Google 在用户身份验证成功后返回的身份验证令牌让用户登录到您的应用程序。
通过 Google One Tap 进行身份验证
注意
需要 OpenID Connect
Google One Tap 仅支持通过 OpenID Connect 进行用户身份验证。 要将 Google 用户日志到您的 Web应用,您必须在App Services身份验证提供者配置中启用OpenID Connect 。
Google One Tap 是一个 Google SDK,用户只需一次单击(或点击)即可注册或登录网站。
例子
基本 Google One Tap 流程
此示例展示了如何在非常基本的 Web 应用中,通过 App Services 设置 Google 身份验证。应用仅包含一个 index.html
文件。
<html lang="en"> <head> <title>Google One Tap Example</title> </head> <body> <h1>Google One Tap Example</h1> <!-- The data-callback HTML attribute sets the callback function that is run when the user logs in. Here we're calling the handleCredentialsResponse JavaScript function defined in the below script section to log the user into App Services. --> <div id="g_id_onload" data-client_id="<your_google_client_id>" data-callback="handleCredentialsResponse" ></div> </body> <!-- Load Atlas App Services --> <script src="https://unpkg.com/realm-web/dist/bundle.iife.js"></script> <!-- Load Google One Tap --> <script src="https://accounts.google.com/gsi/client"></script> <!-- Log in with Realm and Google Authentication --> <script async defer> const app = new Realm.App({ id: "<your_realm_app_id>", }); // Callback used in `data-callback` to handle Google's response and log user into App Services function handleCredentialsResponse(response) { const credentials = Realm.Credentials.google({ idToken: response.credential }); app .logIn(credentials) .then((user) => alert(`Logged in with id: ${user.id}`)); } </script> </html>
使用内置 Google OAuth 2.0 流程
注意
请勿将 OpenID Connect 用于内置 Google OAuth 2.0 流程
- OpenID Connect不适用于Atlas App Services '
- 内置Google OAuth 2.0流程。 如果您希望将 OpenID Connect 与Realm Web SDK结合使用,请使用使用Google One Tap 进行身份验证流程。
Realm Web SDK 包含处理 OAuth 2.0 流程的方法,您不需要安装 Google SDK。内置流程将遵循以下三个主要步骤:
通过 Google 档案调用
app.logIn()
。档案必须指定您的应用的 URL,该 URL 也作为重定向 URI 列出在提供者配置中。一个新窗口打开并显示 Google 身份验证屏幕,用户在该窗口中对您的应用程序进行身份验证和授权。完成后,新窗口将重定向到凭证中指定的 URL。
在重定向的页面上调用
Realm.handleAuthRedirect()
,这会存储用户的 App Services 访问令牌并关闭窗口。原始应用窗口将自动检测访问令牌并结束用户登录流程。
例子
基本 Web 登录流程
此示例展示如何在非常基本的 Web 应用程序中,通过 App Services 设置 Google 身份验证。该应用程序包含以下文件:
. ├── auth.html └── index.html
<html lang="en"> <head> <title>Google Auth Example</title> </head> <body> <h1>Google Auth Example</h1> <button id="google-auth">Authenticate!</button> </body> <!-- Load Realm --> <script src="https://unpkg.com/realm-web/dist/bundle.iife.js"></script> <!-- Log in with App Services and Google Authentication --> <script> const app = new Realm.App({ id: "<Your-App-ID>", }); const authButton = document.getElementById("google-auth"); authButton.addEventListener("click", () => { // The redirect URL should be on the same domain as this app and // specified in the auth provider configuration. const redirectUrl = "http://yourDomain/auth.html"; const credentials = Realm.Credentials.google({ redirectUrl }); // Calling logIn() opens a Google authentication screen in a new window. app .logIn(credentials) .then((user) => { // The logIn() promise will not resolve until you call `handleAuthRedirect()` // from the new window after the user has successfully authenticated. console.log(`Logged in with id: ${user.id}`); }) .catch((err) => console.error(err)); }); </script> </html>
<html lang="en"> <head> <title>Google Auth Redirect</title> </head> <body> <p>Redirects come here for Google Authentication</p> </body> <script> Realm.handleAuthRedirect(); </script> </html>
重要
针对 Google 的内置 OAuth 2.0 重定向限制
由于 OAuth 应用程序验证要求发生变化,内置 OAuth 2.0进程在对Google用户进行身份验证时面临限制。 如果您使用Atlas App Services的重定向流程使用 Google 登录重定向流程,则在应用程序处于开发/测试/过渡阶段时,最多可以有 100 个 Google 用户进行身份验证,并且所有用户在进行身份验证之前都会看到未经验证的应用程序通知。
为了避免这些限制,我们建议您使用官方 Google SDK 获取用户访问令牌,如上所述。
Apple 身份验证
Apple身份验证提供程序允许您通过“使用 Apple 登录”对用户进行身份验证。 您可以使用内置身份验证流程或使用 Apple SDK 进行身份验证。
使用内置 Apple OAuth 2.0 流程
Realm Web SDK 包含处理 OAuth 2.0 流程的方法,并且不需要您安装 Apple JS SDK。内置流程将遵循以下三个主要步骤:
您使用 Apple 档案致电
app.logIn()
。档案必须指定您的应用的 URL,该 URL 也作为重定向 URI 列出在提供者配置中。// The redirect URI should be on the same domain as this app and // specified in the auth provider configuration. const redirectUri = "https://app.example.com/handleOAuthLogin"; const credentials = Realm.Credentials.apple(redirectUri); // Calling logIn() opens an Apple authentication screen in a new window. const user = app.logIn(credentials); // The logIn() promise will not resolve until you call `Realm.handleAuthRedirect()` // from the new window after the user has successfully authenticated. console.log(`Logged in with id: ${user.id}`); 将打开一个新窗口,显示 Apple 身份验证屏幕,用户在该窗口中对您的应用程序进行身份验证和授权。完成后,新窗口将重定向到凭证中指定的 URL。
您在重定向的页面上调用
Realm.handleAuthRedirect()
,该页面将存储用户的应用服务访问令牌并关闭窗口。原始应用窗口将自动检测访问令牌并结束用户登录流程。// When the user is redirected back to your app, handle the redirect to // save the user's access token and close the redirect window. This // returns focus to the original application window and automatically // logs the user in. Realm.handleAuthRedirect();
使用 Apple SDK 进行身份验证
您可以使用官方 Sign in with Apple JS SDK 来处理用户身份验证和重定向流程。 完成身份验证后,Apple JS SDK 将返回一个 ID 令牌,您可以使用该令牌结束用户登录到您应用的流程。
// Get the ID token from the Apple SDK const { id_token } = await AppleID.auth.signIn(); // Define credentials with the ID token from the Apple SDK const credentials = Realm.Credentials.apple(id_token); // Log the user in to your app const user = await app.logIn(credentials);
提示
如果您收到指示 token contains
an invalid number of segments
的 Login failed
错误,请验证您是否传递了 JWT 的 UTF-8 编码字符串版本。
获取用户访问令牌
当用户登录时,Atlas App Services 会为用户创建一个访问令牌,以为他们授予访问您应用的权限。Realm SDK 会自动管理访问令牌,在访问令牌过期时对其进行刷新,并在每次请求中为当前用户提供有效的访问令牌。Realm 不会自动对刷新令牌进行刷新。当刷新令牌过期后,用户必须重新登录。
如果在 SDK 外部发送请求,则需要在每个请求中包含用户的访问令牌,并在令牌过期时手动刷新令牌。
您可以在 SDK 中,通过用户的 Realm.User
对象来访问和刷新已登录用户的访问令牌,如下例所示:
// Gets a valid user access token to authenticate requests async function getValidAccessToken(user) { // An already logged in user's access token might be stale. To // guarantee that the token is valid, refresh it if necessary. await user.refreshAccessToken(); return user.accessToken; }
刷新令牌有效期
刷新令牌会在设定的时间段后过期。刷新令牌过期后,访问令牌将无法再刷新,用户必须重新登录。
有关配置刷新令牌过期时间的信息,请参阅 App Services 文档中的管理用户会话。
登出
要登出任何用户,请在相应的用户实例上调用 User.logOut()
。
登出当前用户:
await app.currentUser.logOut();
按用户 ID 登出用户:
const userId = app.currentUser.id; await app.allUsers[userId].logOut();