账户
Accounts-base
Meteor 账户系统建立在 publish
和 methods
中的 userId
支持之上。核心包添加了存储在数据库中的用户文档的概念,其他包添加了 安全密码认证、与第三方登录服务的集成 以及 预构建的用户界面。
基本的账户系统位于 accounts-base
包中,但应用程序通常会通过添加一个登录提供程序包来自动包含它:accounts-password
、accounts-facebook
、accounts-github
、accounts-google
、accounts-meetup
、accounts-twitter
或 accounts-weibo
。
在 Meteor 指南的 账户 文章中阅读更多关于自定义用户账户的信息。
使用会话存储的账户
默认情况下,Meteor 使用本地存储来存储浏览器会话中的登录令牌等内容。但是,对于某些应用程序,使用会话存储更有意义。您可以通过将以下内容添加到您的设置中来实现此目的
{
// ... all other settings,
"public": {
// ... all your public settings
"packages": {
"accounts": {
"clientStorage": "session"
}
}
}
}
从 Meteor.users
集合中检索当前用户的用户记录。
在客户端,可用的字段将是从服务器发布的那些字段(其他字段在客户端不可用)。默认情况下,服务器发布 username
、emails
和 profile
(用户可写)。有关用户文档中使用的字段的更多信息,请参见 Meteor.users
。
在服务器上,这将从数据库中获取记录。为了提高使用用户文档多次的方法的延迟,请将返回的记录保存到变量中,而不是重新调用 Meteor.user()
。
获取完整的用户文档可能会导致服务器上不必要的数据库使用和客户端上的过度反应,尤其是在您在其中存储大量自定义数据时。因此,建议使用 options
参数仅获取您需要的字段
import { Meteor } from "meteor/meteor";
const userName = Meteor.user({ fields: { "profile.name": 1 } }).profile.name;
与 Meteor.user
相同,但返回一个 Promise 并在服务器上可用。
import { Meteor } from "meteor/meteor";
const user = await Meteor.userAsync();
Meteor.userId
摘要
获取当前用户 ID,如果未登录任何用户,则返回 null
。一个反应式数据源。
import { Meteor } from "meteor/meteor";
Meteor.userId();
此集合包含每个注册用户的单个文档。以下是一个用户文档示例
{
_id: 'QwkSmTCZiw5KDx3L6', // Meteor.userId()
username: 'cool_kid_13', // Unique name
emails: [
// Each email address can only belong to one user.
{ address: '[email protected]', verified: true },
{ address: '[email protected]', verified: false }
],
createdAt: new Date('Wed Aug 21 2013 15:16:52 GMT-0700 (PDT)'),
profile: {
// The profile is writable by the user by default.
name: 'Joe Schmoe'
},
services: {
facebook: {
id: '709050', // Facebook ID
accessToken: 'AAACCgdX7G2...AbV9AZDZD'
},
resume: {
loginTokens: [
{ token: '97e8c205-c7e4-47c9-9bea-8e2ccc0694cd',
when: 1349761684048 }
]
}
}
}
用户文档可以包含您想要存储的有关用户的任何数据。Meteor 对以下字段进行特殊处理
username
:标识用户的唯一字符串。emails
:一个对象的数组,其键为address
和verified
;一个电子邮件地址最多可以属于一个用户。verified
是一个布尔值,如果用户已通过发送到电子邮件的令牌 验证了地址,则为 true。createdAt
:创建用户文档的日期。profile
:用户可以使用任何数据创建和更新的对象。不要在profile
上存储任何您不希望用户编辑的内容,除非您在Meteor.users
集合上设置了拒绝规则。services
:一个包含特定登录服务使用的数据的对象。例如,其reset
字段包含 忘记密码 链接使用的令牌,其resume
字段包含用于在会话之间保持登录状态的令牌。
与所有 Mongo.Collection 一样,您可以在服务器上访问所有文档,但客户端只能访问服务器专门发布的那些文档。您还可以使用所有集合方法,例如服务器上的 Meteor.users.remove
来删除用户。
默认情况下,当前用户的 username
、emails
和 profile
会发布到客户端。您可以使用以下方法发布当前用户的其他字段
Meteor.publish("userData", function () {
if (this.userId) {
return Meteor.users.find(
{ _id: this.userId },
{
fields: { other: 1, things: 1 },
}
);
} else {
this.ready();
}
});
Meteor.subscribe("userData");
如果安装了 autopublish 包,则系统上所有用户信息都会发布到所有客户端。这包括 username
、profile
和 services
中任何旨在公开的字段(例如 services.facebook.id
、services.twitter.screenName
)。此外,在使用 autopublish 时,会为当前登录的用户发布更多信息,包括访问令牌。这允许直接从客户端进行 API 调用,以供允许此操作的服务使用。
默认情况下,用户可以使用 Accounts.createUser
指定他们自己的 profile
字段,并使用 Meteor.users.update
修改它。要允许用户编辑其他字段,请使用 Meteor.users.allow
。要禁止用户对他们的用户文档进行任何修改
import { Meteor } from "meteor/meteor";
Meteor.users.deny({ update: () => true });
Meteor.loggingIn仅限客户端
仅限客户端
摘要
如果当前正在进行登录方法(例如 Meteor.loginWithPassword
、Meteor.loginWithFacebook
或 Accounts.createUser
),则为 true。一个反应式数据源。
import { Meteor } from "meteor/meteor";
Meteor.loggingIn();
例如,accounts-ui
包 使用此功能在处理登录请求时显示动画。
Meteor.loggingOut仅限客户端
仅限客户端
摘要
如果当前正在进行注销方法(例如 Meteor.logout
),则为 true。一个反应式数据源。
import { Meteor } from "meteor/meteor";
Meteor.loggingOut();
Meteor.logout仅限客户端
仅限客户端
摘要
注销用户。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
回调 | 函数 | 可选回调。成功时不带任何参数调用,或失败时带单个 | 否 |
import { Meteor } from "meteor/meteor";
Meteor.logout(
() => {}
);
Meteor.logoutOtherClients仅限客户端
仅限客户端
摘要
注销以当前用户身份登录的其他客户端,但不注销调用此函数的客户端。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
回调 | 函数 | 可选回调。成功时不带任何参数调用,或失败时带单个 | 否 |
import { Meteor } from "meteor/meteor";
Meteor.logoutOtherClients(
() => {}
);
例如,当在用户的浏览器中调用时,该浏览器中的连接将保持登录状态,但任何其他以该用户身份登录的浏览器或 DDP 客户端都将被注销。
Meteor.loginWithPassword仅限客户端
仅限客户端
摘要
使用密码登录用户。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
选择器 | 对象或字符串 | 可以是解释为用户名或电子邮件的字符串;或者是一个具有单个键的对象: | 是 |
密码 | 字符串 | 用户的密码。 | 是 |
回调 | 函数 | 可选回调。成功时不带任何参数调用,或失败时带单个 | 否 |
import { Meteor } from "meteor/meteor";
Meteor.loginWithPassword(
selector,
"password",
() => {}, // this param is optional
);
如果有多个用户名或电子邮件仅在大小写方面不同的用户,则需要进行区分大小写的匹配。尽管 createUser
不会允许您创建具有模棱两可的用户名或电子邮件的用户,但这可能会发生在现有数据库中或如果您直接修改用户集合时。
此方法可能会失败并抛出以下错误之一
- 如果
user
或password
未定义,则为“登录请求的未识别选项 [400]”。 - 如果
user
不是对象或字符串,或者password
不是字符串,则为“匹配失败 [400]”。 - 如果
user
中提供的电子邮件或用户名不属于注册用户,则为“用户未找到 [403]”。 - 如果提供的密码不正确,则为“密码不正确 [403]”。
- 如果
user
没有设置密码,则为“用户没有设置密码 [403]”。
此函数由 accounts-password
包提供。请参见下面的 密码 部分。
Meteor.loginWith<ExternalService>仅限客户端
仅限客户端
摘要
使用外部服务登录用户。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
选项 | 对象 | 否 | |
回调 | 函数 | 可选回调函数。成功时不带参数调用,失败时带单个 | 否 |
import { Meteor } from "meteor/meteor";
Meteor.loginWith<ExternalService>(
options, // this param is optional
() => {}, // this param is optional
);
可用的函数是
Meteor.loginWithMeteorDeveloperAccount
Meteor.loginWithFacebook
options
还可以包含Facebook 的auth_type
参数
Meteor.loginWithGithub
Meteor.loginWithGoogle
options
还可以包含Google 的其他 URI 参数
Meteor.loginWithMeetup
Meteor.loginWithTwitter
options
还可以包含Twitter 的force_login
参数
Meteor.loginWithWeibo
这些函数使用 OAuth 启动与外部服务(例如:Facebook、Google 等)的登录过程。调用时,它们会打开一个新的弹出窗口,加载提供程序的登录页面。用户使用提供程序登录后,弹出窗口会关闭,Meteor 客户端会使用外部服务提供的信息登录到 Meteor 服务器。
请求权限
除了识别用户到您的应用程序之外,某些服务还具有允许您代表用户采取行动的 API。要向用户请求特定权限,请将requestPermissions
选项传递给登录函数。这将导致用户在弹出对话框中看到一个额外的页面,以允许访问其数据。用户的accessToken
(具有访问服务 API 的权限)存储在用户文档的services
字段中。requestPermissions
支持的值因每个登录服务而异,并在其各自的开发者网站上记录。
- Facebook:http://developers.facebook.com/docs/authentication/permissions/
- GitHub:http://developer.github.com/v3/oauth/#scopes
- Google:https://developers.google.com/identity/protocols/googlescopes
- Meetup:http://www.meetup.com/meetup_api/auth/#oauth2-scopes
- Twitter、微博、Meteor 开发者帐户:目前不支持
requestPermissions
。
外部登录服务通常需要在使用前注册和配置您的应用程序。accounts-ui
包提供了一种最简单的方法来执行此操作,它提供了一个分步指南来配置每个服务。但是,数据也可以手动输入到ServiceConfiguration.configurations
集合中,该集合由service-configuration
包导出。
配置服务
首先,添加服务配置包
meteor add service-configuration
然后,在您的应用程序服务器内部(此示例适用于 Weebo 服务),导入ServiceConfiguration
import { ServiceConfiguration } from "meteor/service-configuration";
ServiceConfiguration.configurations.upsert(
{ service: "weibo" },
{
$set: {
loginStyle: "popup",
clientId: "1292962797", // See table below for correct property name!
secret: "75a730b58f5691de5522789070c319bc",
},
}
);
从 Meteor 2.7 开始,您不再需要手动设置配置,而是可以通过在Meteor.settings.packages.service-configuration.<service>
下设置服务来使用 Meteor 设置。所有属性都可以在服务下设置,并将按原样添加到数据库中,因此请确保它们是正确的。对于上面的示例,设置如下所示
{
"packages": {
"service-configuration": {
"weibo": {
"loginStyle": "popup",
"clientId": "1292962797",
"secret": "75a730b58f5691de5522789070c319bc"
}
}
}
}
用于 API 标识符的正确属性名称(即上述示例中的clientId
)取决于使用的登录服务,因此请确保使用正确的属性名称。
属性名称 | 服务 |
---|---|
appId | |
clientId | Github、Google、Meetup、Meteor 开发者帐户、微博 |
consumerKey |
此外,每个外部服务都有自己的登录提供程序包和登录函数。例如,要支持 GitHub 登录,请在终端中运行以下命令
meteor add accounts-github
并使用Meteor.loginWithGithub
函数。
import { Meteor } from "meteor/meteor";
Meteor.loginWithGithub(
{
requestPermissions: ["user", "public_repo"],
},
(error) => {
if (error) {
Session.set("errorMessage", error.reason || "Unknown error");
}
}
);
应用程序启动时,登录服务配置会通过 DDP 从服务器发送到客户端;在配置加载之前,您可能无法调用登录函数。函数Accounts.loginServicesConfigured()
是一个反应式数据源,一旦登录服务配置完成,它将返回 true;在它返回 true 之前,您不应该显示或激活登录按钮。
确保您的$ROOT_URL
与您在外部服务中配置的授权域和回调 URL 匹配(例如,如果您在代理服务器后面运行 Meteor,则$ROOT_URL
应该是外部可访问的 URL,而不是代理服务器内部的 URL)。
手动服务配置
您可以使用Accounts.loginServiceConfiguration
查看和编辑设置集合。
import { Accounts } from "meteor/accounts-base";
Accounts.loginServiceConfiguration.find();
弹出窗口与重定向流程
在使用提供程序(例如 Facebook 或 Google)配置 OAuth 登录时,Meteor 允许您选择基于弹出窗口或重定向的流程。在基于弹出窗口的流程中,当用户登录时,系统会提示他们在弹出窗口中登录提供程序。在基于重定向的流程中,用户的整个浏览器窗口将重定向到登录提供程序,并在登录完成后将窗口重定向回您的应用程序。
您还可以通过将选项传递给Meteor.loginWith<ExternalService>
来选择要执行哪种类型的登录。
通常,基于弹出窗口的流程更可取,因为用户无需在登录流程结束时重新加载整个应用程序。但是,基于弹出窗口的流程需要浏览器功能(例如window.close
和window.opener
),而并非所有移动环境都提供这些功能。特别是,我们建议在以下环境中使用Meteor.loginWith<ExternalService>({ loginStyle: 'redirect' })
- 在 UIWebViews 内部(当您的应用程序加载到移动应用程序中时)
- 在 iOS8 上的 Safari 中(由于错误,不支持
window.close
)
示例
import { Accounts } from "meteor/accounts-base";
Accounts.ui.config({
requestPermissions: {
facebook: ["user_likes"],
github: ["user", "repo"],
},
requestOfflineToken: {
google: true,
},
passwordSignupFields: "USERNAME_AND_OPTIONAL_EMAIL",
});
从 Meteor 2.7 开始,您可以在Meteor.settings.public.packages.accounts-ui-unstyled
下的 Meteor 设置中配置这些设置。
多服务器
accounts-base
包导出了两个构造函数,称为AccountsClient
和AccountsServer
,它们分别用于创建客户端和服务器上可用的Accounts
对象。
此预定义的Accounts
对象(以及Meteor
的类似便捷方法,例如Meteor.logout
)足以在 Meteor 应用程序中实现大多数与帐户相关的逻辑。但是,可以在更复杂的身份验证情况下多次实例化这两个构造函数,以在不同的帐户服务器及其客户端之间创建多个独立的连接。
AccountsCommon
摘要
AccountsClient 和 AccountsServer 的超级构造函数。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
选项 | 对象 | 一个包含以下字段的对象
| 是 |
import { AccountsCommon } from "meteor/accounts-base"";
const accountsCommon = new AccountsCommon(
options
);
AccountsClient
和AccountsServer
类共享一个公共超类AccountsCommon
。在AccountsCommon.prototype
上定义的方法将通过预定义的Accounts
对象(最常见)或使用AccountsClient
或AccountsServer
构造函数创建的任何自定义accountsClientOrServer
对象(不太常见)在客户端和服务器上都可用。
以下是一些这样的方法
accountsCommon.userId
摘要
获取当前用户 ID,如果未登录任何用户,则返回 null
。一个反应式数据源。
// accountsCommon is an instance of AccountsCommon
accountsCommon.userId();
accountsCommon.user
摘要
获取当前用户记录,如果未登录任何用户,则返回null
。一个反应式数据源。在服务器上,此函数返回一个 Promise。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
选项 | 对象 | 否 |
// accountsCommon is an instance of AccountsCommon
accountsCommon.user(
options
);
accountsCommon.config
摘要
设置全局帐户选项。您也可以在Meteor.settings.packages.accounts
中设置这些选项,而无需调用此函数。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
选项 | 对象 | 是 |
// accountsCommon is an instance of AccountsCommon
accountsCommon.config(
options
);
从 Meteor 2.5 开始,您可以在 Meteor.settings.packages.accounts-base
下的 Meteor 设置中设置这些选项。请注意,由于设置文件的性质,您将无法设置需要函数的参数。
accountsCommon.onLogin
摘要
注册一个在登录尝试成功后调用的回调函数。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
函数 | 函数 | 登录成功时调用的回调函数。回调函数接收一个包含登录详细信息的单个对象。此对象包含客户端和服务器上的登录结果类型(密码、恢复等)。在服务器上注册的 | 是 |
// accountsCommon is an instance of AccountsCommon
accountsCommon.onLogin(
() => {}
);
有关详细信息,请参阅 AccountsCommon#onLoginFailure 的描述。
accountsCommon.onLoginFailure
摘要
注册一个在登录尝试失败后调用的回调函数。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
函数 | 函数 | 登录失败后调用的回调函数。 | 是 |
// accountsCommon is an instance of AccountsCommon
accountsCommon.onLoginFailure(
() => {}
);
对于每次登录尝试,都会调用 onLogin
或 onLoginFailure
回调函数之一。onLogin
回调函数在用户成功登录后调用。onLoginFailure
回调函数在登录尝试被拒绝后调用。
这些函数返回一个包含单个方法 stop
的对象。调用 stop()
将取消注册回调函数。
在服务器端,回调函数接收一个参数,与 validateLoginAttempt
中的尝试信息对象相同。在客户端,回调函数参数是一个包含单个 error
属性的对象,该属性设置为从登录失败尝试中接收到的 Error
对象。
在服务器端,func
回调函数接收一个参数,其中包含以下对象。在客户端,不传递任何参数。
import { AccountsCommon } from "meteor/accounts-base";
const options = {
//...
};
const accountsCommon = new AccountsCommon(options);
accountsCommon.onLogout(({ user, connection, collection }) => {
console.log(user);
// ˆˆˆˆˆˆ The Meteor user object of the user which just logged out
console.log(connection);
// ˆˆˆˆˆˆ The connection object the request came in on. See
// `Meteor.onConnection` for details.
console.log(collection);
// ˆˆˆˆˆˆ The `collection` The name of the Mongo.Collection or the
// Mongo.Collection object to hold the users.
});
AccountsClient仅限客户端
仅限客户端
摘要
客户端上 Accounts
对象的构造函数。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
选项 | 对象 | 一个包含以下字段的对象 | 是 |
import { AccountsClient } from "meteor/accounts-base"";
const accountsClient = new AccountsClient(
options
);
在任何 AccountsClient
实例化中,最多应提供 options.connection
和 options.ddpUrl
之一。如果两者都没有提供,则 Meteor.connection
将用作 AccountsClient
实例的 .connection
属性。
请注意,由于使用了诸如 window.localStorage
之类的浏览器 API,AccountsClient
目前仅在客户端可用。但是,原则上,可能需要从一个服务器到另一个远程账户服务器建立客户端连接。如果您发现自己需要此服务器到服务器的功能,请 告知我们。
这些方法定义在 AccountsClient.prototype
上,因此仅在客户端可用
accountsClient.loggingIn仅限客户端
仅限客户端
摘要
如果当前正在进行登录方法(例如 Meteor.loginWithPassword
、Meteor.loginWithFacebook
或 Accounts.createUser
),则为 true。一个反应式数据源。
// accountsClient is an instance of AccountsClient
accountsClient.loggingIn();
accountsClient.logout仅限客户端
仅限客户端
摘要
注销用户。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
回调 | 函数 | 可选回调。成功时不带任何参数调用,或失败时带单个 | 否 |
// accountsClient is an instance of AccountsClient
accountsClient.logout(
() => {}
);
accountsClient.logoutOtherClients仅限客户端
仅限客户端
摘要
注销以当前用户身份登录的其他客户端,但不注销调用此函数的客户端。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
回调 | 函数 | 可选回调。成功时不带任何参数调用,或失败时带单个 | 否 |
// accountsClient is an instance of AccountsClient
accountsClient.logoutOtherClients(
() => {}
);
AccountsServer仅限服务器
仅限服务器
摘要
服务器上 Accounts
命名空间的构造函数。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
服务器 | 对象 | 服务器对象,例如 | 是 |
import { AccountsServer } from "meteor/accounts-base"";
const accountsServer = new AccountsServer(
server
);
这些方法定义在 AccountsServer.prototype
上,因此仅在服务器上可用
accountsServer.validateNewUser仅限服务器
仅限服务器
摘要
设置对新用户创建的限制。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
函数 | 函数 | 每当创建新用户时调用。接收新用户对象,并返回 true 以允许创建或返回 false 以中止创建。 | 是 |
// accountsServer is an instance of AccountsServer
accountsServer.validateNewUser(
() => {}
);
可以多次调用此函数。如果任何函数返回 false
或抛出错误,则新用户创建将被中止。要设置特定的错误消息(将由 accounts-ui
显示),请抛出一个新的 Meteor.Error
。
示例
import { Accounts } from "meteor/accounts-base";
// Validate username, sending a specific error message on failure.
Accounts.validateNewUser((user) => {
if (user.username && user.username.length >= 3) {
return true;
} else {
throw new Meteor.Error(403, "Username must have at least 3 characters");
}
});
// Validate username, without a specific error message.
Accounts.validateNewUser((user) => {
return user.username !== "root";
});
如果用户是在客户端登录尝试的一部分中创建的(例如,从客户端调用 Accounts.createUser
或 首次使用外部服务登录),则这些回调函数将在 Accounts.validateLoginAttempt
回调函数之前调用。如果这些回调函数成功但那些回调函数失败,则用户仍将被创建,但连接将不会以该用户身份登录。
accountsServer.onCreateUser仅限服务器
仅限服务器
摘要
自定义新用户创建。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
函数 | 函数 | 每当创建新用户时调用。返回新用户对象,或抛出一个 | 是 |
当您需要执行的操作不仅仅是接受或拒绝新用户创建时,可以使用此函数。使用此函数,您可以以编程方式控制新用户文档的内容。
您传递的函数将使用两个参数调用:options
和 user
。options
参数来自基于密码的用户或外部服务登录流程的 Accounts.createUser
。options
可能来自不受信任的客户端,因此请确保验证从中读取的任何值。user
参数在服务器上创建,并包含一个建议的用户对象,其中包含用户登录所需的所有自动生成的字段,包括 _id
。
该函数应返回用户文档(传递的文档或新创建的对象),并包含所需的任何修改。返回的文档将直接插入到 Meteor.users
集合中。
默认创建用户函数只是将 options.profile
复制到新用户文档中。调用 onCreateUser
将覆盖默认钩子。这只能调用一次。
示例
import { Accounts } from "meteor/accounts-base";
// Support for playing D&D: Roll 3d6 for dexterity.
Accounts.onCreateUser((options, user) => {
const customizedUser = Object.assign(
{
dexterity: _.random(1, 6) + _.random(1, 6) + _.random(1, 6),
},
user
);
// We still want the default hook's 'profile' behavior.
if (options.profile) {
customizedUser.profile = options.profile;
}
return customizedUser;
});
accountsServer.validateLoginAttempt仅限服务器
仅限服务器
摘要
验证登录尝试。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
函数 | 函数 | 每当尝试登录(成功或失败)时调用。可以通过返回虚假值或抛出异常来中止登录。 | 是 |
使用回调函数调用 validateLoginAttempt
以在登录尝试时调用。它返回一个包含单个方法 stop
的对象。调用 stop()
将取消注册回调函数。
进行登录尝试时,注册的验证登录回调函数将使用一个参数调用,您可以查看示例
import { AccountsServer } from "meteor/accounts-base";
const options = {
//...
};
const accountsServer = new AccountsServer(options);
accountsServer.validateLoginAttempt(
({
type, // String
allowed, // Boolean
error, // Error
user, // Object
connection, // Object
collection, // Object
methodName, // String
methodArguments, // Array<String>
}) => {
console.log(type);
// ˆˆˆˆˆˆ The service name, such as "password" or "twitter".
console.log(allowed);
// ˆˆˆˆˆˆ Whether this login is allowed and will be successful (if not aborted
// by any of the validateLoginAttempt callbacks). False if the login
// will not succeed (for example, an invalid password or the login was
// aborted by a previous validateLoginAttempt callback).
console.log(error);
// ˆˆˆˆˆˆ When `allowed` is false, the exception describing why the login
// failed. It will be a `Meteor.Error` for failures reported to the
// user (such as invalid password), and can be a another kind of
// exception for internal errors.
console.log(user);
// ˆˆˆˆˆˆ When it is known which user was attempting to login,
// the Meteor user object. This will always be present for successful logins.
console.log(connection);
// ˆˆˆˆˆˆ The `connection` object the request came in on. See
// [`Meteor.onConnection`](#meteor_onconnection) for details.
console.log(collection);
// ˆˆˆˆˆˆ The `collection` The name of the Mongo.Collection or the
// Mongo.Collection object to hold the users.
console.log(methodName);
// ˆˆˆˆˆˆ The name of the Meteor method being used to login.
// For example, "login", "loginWithPassword", or "loginWith<ExternalService>".
console.log(methodArguments);
// ˆˆˆˆˆˆ An array of the arguments passed to the login method.
// For example, `["username", "password"]`
}
);
验证登录回调函数必须返回真值才能继续登录。如果回调函数返回虚假值或抛出异常,则登录将被中止。抛出 Meteor.Error
将向用户报告错误原因。
所有注册的验证登录回调都会被调用,即使其中一个回调中止了登录。由于登录现在不会成功,因此后面的回调将看到allowed
字段设置为false
。这允许后面的回调覆盖之前回调的错误;例如,您可以用不同的消息覆盖“密码错误”错误。
如果登录尝试已被确定失败,则通常不需要运行没有明确尝试覆盖先前错误的验证登录回调,并且应该以以下内容开头
if (!attempt.allowed) {
return false;
}
accountsServer.beforeExternalLogin仅限服务器
仅限服务器
摘要
验证来自外部服务的登录
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
函数 | 函数 | 每当尝试从外部服务登录/创建用户时调用。可以通过传递虚假值或抛出异常来中止基于此登录的登录或用户创建。 | 是 |
如果您需要验证来自外部服务的用户是否允许登录或创建帐户,请使用此钩子。
import { AccountsServer } from "meteor/accounts-base";
const options = {
//...
};
const accountsServer = new AccountsServer(options);
accountsServer.beforeExternalLogin(({ type, data, user }) => {
console.log(type);
// ˆˆˆˆˆˆ The service name, such as "google" or "twitter". Is a String
console.log(data);
// ˆˆˆˆˆˆ Data retrieved from the service (eg: email, name, etc)
// Is an Object.
console.log(user);
// ˆˆˆˆˆˆ If user was found in the database that matches the criteria from the service,
// their data will be provided here. Is an Object.
});
您应该返回一个Boolean
值,如果应继续登录/注册则返回true
,如果应终止则返回false
。如果终止,登录尝试将抛出错误403
,消息为:Login forbidden
。
accountsServer.setAdditionalFindUserOnExternalLogin仅限服务器
仅限服务器
摘要
自定义外部登录的用户选择
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
函数 | 函数 | 每当用户通过 oauth 登录且未找到具有服务 ID 的用户时调用。返回用户或 undefined。 | 是 |
当允许您的用户使用外部服务进行身份验证时,该过程最终将调用Accounts.updateOrCreateUserFromExternalService
。默认情况下,这将搜索具有service.<servicename>.id
的用户,如果未找到,则会创建一个新用户。由于这并不总是理想的,您可以使用此钩子作为逃生舱来查找具有不同选择器(可能是emails.address
或username
)的用户。请注意,只有在使用service.<servicename>.id
选择器未找到用户时才会调用此函数。
该函数将被调用,并带有一个参数,即 info 对象
import { AccountsServer } from "meteor/accounts-base";
const options = {
//...
};
const accountsServer = new AccountsServer(options);
accountsServer.setAdditionalFindUserOnExternalLogin(
({ serviceName, serviceData, options }) => {
// serviceName: String
// The external service name, such as "google" or "twitter".
// serviceData: Object
// The data returned by the service oauth request.
// options: Object
// An optional arugment passed down from the oauth service that may contain
// additional user profile information. As the data in `options` comes from an
// external source, make sure you validate any values you read from it.
}
);
该函数应该返回一个用户文档或undefined
。返回用户将导致填充用户文档中的service.<servicename>
,而返回undefined
将导致创建一个新用户帐户。如果您希望不创建新帐户,则可以抛出错误而不是返回。
示例
// If a user has already been created, and used their Google email, this will
// allow them to sign in with the Meteor.loginWithGoogle method later, without
// creating a new user.
Accounts.setAdditionalFindUserOnExternalLogin(
({ serviceName, serviceData }) => {
if (serviceName === "google") {
// Note: Consider security implications. If someone other than the owner
// gains access to the account on the third-party service they could use
// the e-mail set there to access the account on your app.
// Most often this is not an issue, but as a developer you should be aware
// of how bad actors could play.
return Accounts.findUserByEmail(serviceData.email);
}
}
);
accountsServer.registerLoginHandler仅限服务器
仅限服务器
摘要
注册新的登录处理程序。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
名称 | 字符串 | 登录方法的类型,例如 oauth、password 等。 | 否 |
处理程序 | 函数 | 一个接收选项对象(作为参数传递给 | 是 |
// accountsServer is an instance of AccountsServer
accountsServer.registerLoginHandler(
"name", // this param is optional
() => {},
);
使用此方法注册您自己的自定义身份验证方法。所有其他内置帐户包也使用此方法与帐户系统集成。
可以注册多个登录处理程序。当发出登录请求时,它将遍历所有这些处理程序以找到其自己的处理程序。
注册的处理程序回调将被调用,并带有一个参数,即来自登录方法的options
对象。例如,如果您想使用纯文本密码登录,options
可能是{ user: { username: <username> }, password: <password> }
,或{ user: { email: <email> }, password: <password> }
。
如果登录处理程序不打算处理登录请求,则应返回undefined
,否则返回登录结果对象。
速率限制
默认情况下,已向DDPRateLimiter
添加了一些规则,这些规则将登录、新用户注册和密码重置调用限制为每个会话每 10 秒 5 个请求。这些是对字典攻击的基本解决方案,在字典攻击中,恶意用户试图通过尝试所有可能的密码来猜测合法用户的密码。
可以通过调用Accounts.removeDefaultRateLimit()
删除这些速率限制规则。有关更多信息,请参阅DDPRateLimiter
文档。
accountsServer.addDefaultRateLimit仅限服务器
仅限服务器
摘要
添加一个默认规则,限制登录、创建新用户和重置密码,每个连接每 10 秒 5 次。
// accountsServer is an instance of AccountsServer
accountsServer.addDefaultRateLimit();
accountsServer.removeDefaultRateLimit仅限服务器
仅限服务器
摘要
删除默认速率限制规则
// accountsServer is an instance of AccountsServer
accountsServer.removeDefaultRateLimit();
密码
accounts-password
包包含一个完整的基于密码的身份验证系统。除了基本的基于用户名和密码的登录过程外,它还支持基于电子邮件的登录,包括地址验证和密码恢复电子邮件。
Meteor 服务器使用bcrypt算法存储密码。如果服务器的数据库遭到破坏,这有助于防止尴尬的密码泄露。
要向您的应用程序添加密码支持,请在您的终端中运行此命令
meteor add accounts-password
除了配置
MAIL_URL
之外,至关重要的是您在Accounts.emailTemplates
中设置正确的价值(特别是from
地址),以确保正确发送电子邮件!
您可以使用以下函数构建自己的用户界面,或使用accounts-ui
包包含一个用于基于密码的登录的交钥匙用户界面。
Accounts.createUser
摘要
创建一个新用户。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
选项 | 对象 | 是 | |
回调 | 函数 | 仅限客户端,可选回调。成功时不带参数调用,失败时带一个 | 否 |
import { Accounts } from "meteor/accounts-base";
Accounts.createUser(
options,
() => {}, // this param is optional
);
在客户端,此函数在成功完成时以新创建的用户身份登录。在服务器上,它返回新创建的用户 ID。
在客户端,您必须传递password
和至少一个username
或email
——足够的信息供用户稍后能够再次登录。如果现有用户的用户名或电子邮件仅在大小写方面有所不同,则createUser
将失败。回调的error.reason
将是'Username already exists.'
或'Email already exists.'
在后一种情况下,用户可以然后登录或重置他们的密码。
在服务器上,您不需要指定password
,但用户将无法登录,直到它拥有密码(例如,使用Accounts.setPasswordAsync
设置)。要在服务器上创建没有密码的帐户并仍然允许用户选择自己的密码,请使用email
选项调用createUser
,然后调用Accounts.sendEnrollmentEmail
。这将向用户发送一封包含设置其初始密码链接的电子邮件。
默认情况下,profile
选项将直接添加到新用户文档中。要覆盖此行为,请使用Accounts.onCreateUser
。
此函数仅用于创建具有密码的用户。外部服务登录流程不使用此函数。
不要直接修改Meteor.users
集合中的文档,请使用这些便捷函数,这些函数在更新前会正确检查不区分大小写的重复项。
Accounts.createUserAsync
摘要
创建一个新用户并返回其结果的 promise。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
选项 | 对象 | 是 |
import { Accounts } from "meteor/accounts-base";
Accounts.createUserAsync(
options
);
Accounts.createUserVerifyingEmail仅限服务器
仅限服务器
摘要
异步创建用户并在options.email
被告知时发送电子邮件。然后,如果来自Accounts
包的sendVerificationEmail
选项已启用,则如果options.password
被告知,您将发送验证电子邮件,否则您将发送注册电子邮件。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
选项 | 对象 | 创建用户时要传递的选项对象 | 是 |
import { Accounts } from "meteor/accounts-base";
Accounts.createUserVerifyingEmail(
options
);
Accounts.setUsername仅限服务器
仅限服务器
摘要
异步更改用户的用户名。使用此方法而不是直接更新数据库。如果存在用户名仅在大小写方面有所不同的用户,则操作将失败。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
用户 ID | 字符串 | 要更新的用户 ID。 | 是 |
新用户名 | 字符串 | 用户的新的用户名。 | 是 |
import { Accounts } from "meteor/accounts-base";
Accounts.setUsername(
"userId",
"newUsername",
);
Accounts.addEmailAsync仅限服务器
仅限服务器
摘要
异步为用户添加电子邮件地址。使用此方法而不是直接更新数据库。如果存在电子邮件地址仅在大小写方面有所不同的其他用户,则操作将失败。但是,如果指定的用户具有仅在大小写方面有所不同的现有电子邮件,我们将替换它。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
用户 ID | 字符串 | 要更新的用户 ID。 | 是 |
新电子邮件 | 字符串 | 用户的新的电子邮件地址。 | 是 |
已验证 | Boolean | 可选 - 是否应将新的电子邮件地址标记为已验证。默认为 false。 | 否 |
import { Accounts } from "meteor/accounts-base";
Accounts.addEmailAsync(
"userId",
"newEmail",
false, // this param is optional
);
默认情况下,电子邮件地址将添加{ verified: false }
。使用Accounts.sendVerificationEmail
发送包含用户可用于验证其电子邮件地址的链接的电子邮件。
Accounts.removeEmail仅限服务器
仅限服务器
摘要
异步删除用户的电子邮件地址。使用此方法而不是直接更新数据库。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
用户 ID | 字符串 | 要更新的用户 ID。 | 是 |
电子邮件 | 字符串 | 要删除的电子邮件地址。 | 是 |
import { Accounts } from "meteor/accounts-base";
Accounts.removeEmail(
"userId",
"email",
);
Accounts.verifyEmail仅限客户端
仅限客户端
摘要
将用户的电子邮件地址标记为已验证。如果用户未启用 2FA,则之后登录用户。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
令牌 | 字符串 | 从验证 URL 中检索到的令牌。 | 是 |
回调 | 函数 | 可选回调。成功时不带任何参数调用,或失败时带单个 | 否 |
import { Accounts } from "meteor/accounts-base";
Accounts.verifyEmail(
"token",
() => {}, // this param is optional
);
如果尝试验证电子邮件的用户启用了 2FA,则将抛出此错误
- "电子邮件已验证,但用户未登录,因为已启用 2FA [2fa-enabled]": 如果用户启用了 2FA,则不再自动登录用户。
此函数接受传递给使用Accounts.onEmailVerificationLink
注册的回调的令牌。
Accounts.findUserByUsername仅限服务器
仅限服务器
摘要
异步查找具有指定用户名的用户。首先尝试区分大小写匹配用户名;如果失败,则尝试不区分大小写;但如果多个用户匹配不区分大小写的搜索,则返回 null。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
用户名 | 字符串 | 要查找的用户名 | 是 |
选项 | 对象 | 否 |
import { Accounts } from "meteor/accounts-base";
/** @returns Promise<Object> */
const result = Accounts.findUserByUsername(
"username",
options, // this param is optional
);
Accounts.findUserByEmail仅限服务器
仅限服务器
摘要
异步查找指定电子邮件的用户。首先尝试区分大小写匹配电子邮件;如果失败,则尝试不区分大小写;但如果多个用户匹配不区分大小写的搜索,则返回 null。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
电子邮件 | 字符串 | 要查找的电子邮件地址 | 是 |
选项 | 对象 | 否 |
import { Accounts } from "meteor/accounts-base";
/** @returns Promise<Object> */
const result = Accounts.findUserByEmail(
"email",
options, // this param is optional
);
使用以下函数从服务器或客户端启动密码更改或重置。
Accounts.changePassword仅限客户端
仅限客户端
摘要
更改当前用户的密码。必须已登录。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
oldPassword | 字符串 | 用户的当前密码。此密码**不会**以明文形式通过网络发送。 | 是 |
newPassword | 字符串 | 用户的新的密码。此密码**不会**以明文形式通过网络发送。 | 是 |
回调 | 函数 | 可选回调。成功时不带任何参数调用,或失败时带单个 | 否 |
import { Accounts } from "meteor/accounts-base";
Accounts.changePassword(
"oldPassword",
"newPassword",
() => {}, // this param is optional
);
Accounts.forgotPassword仅限客户端
仅限客户端
摘要
请求忘记密码邮件。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
选项 | 对象 | 是 | |
回调 | 函数 | 可选回调。成功时不带任何参数调用,或失败时带单个 | 否 |
import { Accounts } from "meteor/accounts-base";
Accounts.forgotPassword(
options,
() => {}, // this param is optional
);
这会触发对服务器上的Accounts.sendResetPasswordEmail
的调用。当用户访问此电子邮件中的链接时,将调用使用Accounts.onResetPasswordLink
注册的回调。
如果您正在使用accounts-ui
包,则此操作会自动处理。否则,您有责任提示用户输入新密码并调用resetPassword
。
Accounts.resetPassword仅限客户端
仅限客户端
摘要
使用在电子邮件中收到的令牌重置用户的密码。如果用户没有启用 2FA,则之后登录用户。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
令牌 | 字符串 | 从重置密码 URL 中检索到的令牌。 | 是 |
newPassword | 字符串 | 用户的新的密码。此密码**不会**以明文形式通过网络发送。 | 是 |
回调 | 函数 | 可选回调。成功时不带任何参数调用,或失败时带单个 | 否 |
import { Accounts } from "meteor/accounts-base";
Accounts.resetPassword(
"token",
"newPassword",
() => {}, // this param is optional
);
此函数接受传递到使用AccountsClient#onResetPasswordLink
和Accounts.onEnrollmentLink
注册的回调中的令牌。
如果尝试重置密码的用户启用了 2FA,则会抛出此错误
- "已更改密码,但用户未登录,因为已启用 2FA [2fa-enabled]": 如果用户启用了 2FA,则不再自动登录用户。
Accounts.setPasswordAsync仅限服务器
仅限服务器
摘要
强制更改用户的密码。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
用户 ID | 字符串 | 要更新的用户 ID。 | 是 |
newPassword | 字符串 | 用户的新的密码。 | 是 |
选项 | 对象 | 否 |
import { Accounts } from "meteor/accounts-base";
Accounts.setPasswordAsync(
"userId",
"newPassword",
options, // this param is optional
);
Accounts.sendResetPasswordEmail仅限服务器
仅限服务器
摘要
异步发送一封电子邮件,其中包含用户可以用来重置其密码的链接。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
用户 ID | 字符串 | 要发送电子邮件的用户 ID。 | 是 |
电子邮件 | 字符串 | 可选。要发送电子邮件的用户地址。此地址必须位于用户的 | 否 |
extraTokenData | 对象 | 可选的要添加到令牌记录中的其他数据。 | 否 |
extraParams | 对象 | 可选的要添加到重置 URL 中的其他参数。 | 否 |
import { Accounts } from "meteor/accounts-base";
/** @returns Promise<Object> */
const result = Accounts.sendResetPasswordEmail(
"userId",
"email", // this param is optional
extraTokenData, // this param is optional
extraParams, // this param is optional
);
当用户访问此电子邮件中的链接时,将调用使用AccountsClient#onResetPasswordLink
注册的回调。
要自定义电子邮件内容,请参阅Accounts.emailTemplates
。
Accounts.sendEnrollmentEmail仅限服务器
仅限服务器
摘要
异步发送一封电子邮件,其中包含用户可以用来设置其初始密码的链接。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
用户 ID | 字符串 | 要发送电子邮件的用户 ID。 | 是 |
电子邮件 | 字符串 | 可选。要发送电子邮件的用户地址。此地址必须位于用户的 | 否 |
extraTokenData | 对象 | 可选的要添加到令牌记录中的其他数据。 | 否 |
extraParams | 对象 | 可选的要添加到注册 URL 中的其他参数。 | 否 |
import { Accounts } from "meteor/accounts-base";
/** @returns Promise<Object> */
const result = Accounts.sendEnrollmentEmail(
"userId",
"email", // this param is optional
extraTokenData, // this param is optional
extraParams, // this param is optional
);
当用户访问此电子邮件中的链接时,将调用使用Accounts.onEnrollmentLink
注册的回调。
要自定义电子邮件内容,请参阅Accounts.emailTemplates
。
Accounts.sendVerificationEmail仅限服务器
仅限服务器
摘要
异步发送一封电子邮件,其中包含用户可以用来验证其电子邮件地址的链接。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
用户 ID | 字符串 | 要发送电子邮件的用户 ID。 | 是 |
电子邮件 | 字符串 | 可选。要发送电子邮件的用户地址。此地址必须位于用户的 | 否 |
extraTokenData | 对象 | 可选的要添加到令牌记录中的其他数据。 | 否 |
extraParams | 对象 | 可选的要添加到验证 URL 中的其他参数。 | 否 |
import { Accounts } from "meteor/accounts-base";
/** @returns Promise<Object> */
const result = Accounts.sendVerificationEmail(
"userId",
"email", // this param is optional
extraTokenData, // this param is optional
extraParams, // this param is optional
);
当用户访问此电子邮件中的链接时,将调用使用Accounts.onEmailVerificationLink
注册的回调。
要自定义电子邮件内容,请参阅Accounts.emailTemplates
。
Accounts.onResetPasswordLink仅限客户端
仅限客户端
摘要
注册一个函数,在点击由Accounts.sendResetPasswordEmail
发送的电子邮件中的重置密码链接时调用。此函数应在顶级代码中调用,而不是在Meteor.startup()
内部调用。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
回调 | 函数 | 要调用的函数。它有两个参数
| 是 |
import { Accounts } from "meteor/accounts-base";
Accounts.onResetPasswordLink(
() => {}
);
Accounts.onEnrollmentLink仅限客户端
仅限客户端
摘要
注册一个函数,在点击由Accounts.sendEnrollmentEmail
发送的电子邮件中的帐户注册链接时调用。此函数应在顶级代码中调用,而不是在Meteor.startup()
内部调用。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
回调 | 函数 | 要调用的函数。它有两个参数
| 是 |
import { Accounts } from "meteor/accounts-base";
Accounts.onEnrollmentLink(
() => {}
);
Accounts.onEmailVerificationLink仅限客户端
仅限客户端
摘要
注册一个函数,在点击由Accounts.sendVerificationEmail
发送的电子邮件中的电子邮件验证链接时调用。此函数应在顶级代码中调用,而不是在Meteor.startup()
内部调用。
参数
源代码名称 | 类型 | 描述 | 必需 |
---|---|---|---|
回调 | 函数 | 要调用的函数。它有两个参数
| 是 |
import { Accounts } from "meteor/accounts-base";
Accounts.onEmailVerificationLink(
() => {}
);
这是一个Object
,其中包含几个字段,用于为sendResetPasswordEmail
、sendEnrollmentEmail
和sendVerificationEmail
发送的电子邮件生成文本/html。
通过为其赋值来设置对象的字段
from
:(**必需**)RFC5322 发件人地址的String
。默认情况下,电子邮件是从[email protected]
发送的。**如果您希望电子邮件正确发送,则应将其更改为您自己的域,因为大多数电子邮件提供商将拒绝从example.com
发送的邮件。**siteName
:应用程序的公开名称。默认为应用程序的 DNS 名称(例如:awesome.meteor.com
)。headers
:一个Object
,用于自定义电子邮件标头,如Email.send
中所述。resetPassword
:一个包含以下字段的Object
from
:一个Function
,用于覆盖由emailTemplates.from
字段定义的from
地址。subject
:一个Function
,它接收一个用户对象并返回重置密码电子邮件主题行的String
。text
:一个可选的Function
,它接收一个用户对象和一个 URL,并返回重置密码电子邮件的正文文本。html
:一个可选的Function
,它接收一个用户对象和一个 URL,并返回重置密码电子邮件的正文 html。enrollAccount
:与resetPassword
相同,但用于新帐户的初始密码设置。verifyEmail
:与resetPassword
相同,但用于验证用户的电子邮件地址。
示例
import { Accounts } from "meteor/accounts-base";
Accounts.emailTemplates.siteName = "AwesomeSite";
Accounts.emailTemplates.from = "AwesomeSite Admin <[email protected]>";
Accounts.emailTemplates.enrollAccount.subject = (user) => {
return `Welcome to Awesome Town, ${user.profile.name}`;
};
Accounts.emailTemplates.enrollAccount.text = (user, url) => {
return (
"You have been selected to participate in building a better future!" +
" To activate your account, simply click the link below:\n\n" +
url
);
};
Accounts.emailTemplates.resetPassword.from = () => {
// Overrides the value set in `Accounts.emailTemplates.from` when resetting
// passwords.
return "AwesomeSite Password Reset <[email protected]>";
};
Accounts.emailTemplates.verifyEmail = {
subject() {
return "Activate your account now!";
},
text(user, url) {
return `Hey ${user}! Verify your e-mail by following this link: ${url}`;
},
};
为此包启用 2FA
您可以通过使用accounts-2fa包将 2FA 添加到您的登录流程中。您可以在此处找到一个显示此外观的示例。