Accounts (multi-server)
The accounts-base
package exports two constructors, called
AccountsClient
and AccountsServer
, which are used to create the
Accounts
object that is available on the client and the server,
respectively.
This predefined Accounts
object (along with similar convenience methods
of Meteor
, such as Meteor.logout
) is sufficient to
implement most accounts-related logic in Meteor apps. Nevertheless, these
two constructors can be instantiated more than once, to create multiple
independent connections between different accounts servers and their
clients, in more complicated authentication situations.
new AccountsCommon(options)
Super-constructor for AccountsClient and AccountsServer.
The AccountsClient
and AccountsServer
classes share a common
superclass, AccountsCommon
. Methods defined on
AccountsCommon.prototype
will be available on both the client and the
server, via the predefined Accounts
object (most common) or any custom
accountsClientOrServer
object created using the AccountsClient
or
AccountsServer
constructors (less common).
Here are a few of those methods:
Get the current user id, or null
if no user is logged in. A reactive data source.
Get the current user record, or null
if no user is logged in. A reactive data source.
Options
- fields Mongo Field Specifier
-
Dictionary of fields to return or exclude.
Set global accounts options. You can also set these in Meteor.settings.packages.accounts
without the need to call this function.
Options
- sendVerificationEmail Boolean
-
New users with an email address will receive an address verification email.
- forbidClientAccountCreation Boolean
-
Calls to
createUser
from the client will be rejected. In addition, if you are using accounts-ui, the "Create account" link will not be available. - restrictCreationByEmailDomain String or Function
-
If set to a string, only allows new users if the domain part of their email address matches the string. If set to a function, only allows new users if the function returns true. The function is passed the full email address of the proposed new user. Works with password-based sign-in and external services that expose email addresses (Google, Facebook, GitHub). All existing users still can log in after enabling this option. Example:
Accounts.config({ restrictCreationByEmailDomain: 'school.edu' })
. - loginExpiration Number
-
The number of milliseconds from when a user logs in until their token expires and they are logged out, for a more granular control. If
loginExpirationInDays
is set, it takes precedent. - loginExpirationInDays Number
-
The number of days from when a user logs in until their token expires and they are logged out. Defaults to 90. Set to
null
to disable login expiration. - oauthSecretKey String
-
When using the
oauth-encryption
package, the 16 byte key using to encrypt sensitive account credentials in the database, encoded in base64. This option may only be specified on the server. See packages/oauth-encryption/README.md for details. - passwordResetTokenExpirationInDays Number
-
The number of days from when a link to reset password is sent until token expires and user can't reset password with the link anymore. Defaults to 3.
- passwordResetTokenExpiration Number
-
The number of milliseconds from when a link to reset password is sent until token expires and user can't reset password with the link anymore. If
passwordResetTokenExpirationInDays
is set, it takes precedent. - passwordEnrollTokenExpirationInDays Number
-
The number of days from when a link to set initial password is sent until token expires and user can't set password with the link anymore. Defaults to 30.
- passwordEnrollTokenExpiration Number
-
The number of milliseconds from when a link to set initial password is sent until token expires and user can't set password with the link anymore. If
passwordEnrollTokenExpirationInDays
is set, it takes precedent. - ambiguousErrorMessages Boolean
-
Return ambiguous error messages from login failures to prevent user enumeration. Defaults to false.
- bcryptRounds Number
-
Allows override of number of bcrypt rounds (aka work factor) used to store passwords. The default is 10.
- defaultFieldSelector Mongo Field Specifier
-
To exclude by default large custom fields from
Meteor.user()
andMeteor.findUserBy...()
functions when called without a field selector, and allonLogin
,onLoginFailure
andonLogout
callbacks. Example:Accounts.config({ defaultFieldSelector: { myBigArray: 0 }})
. Beware when using this. If, for instance, you do not includeemail
when excluding the fields, you can have problems with functions likeforgotPassword
that will break because they won't have the required data available. It's recommend that you always keep the fields_id
,username
, andemail
. - collection String or , or undefined
-
A collection name or a Mongo.Collection object to hold the users.
- loginTokenExpirationHours Number
-
When using the package
accounts-2fa
, use this to set the amount of time a token sent is valid. As it's just a number, you can use, for example, 0.5 to make the token valid for just half hour. The default is 1 hour. - tokenSequenceLength Number
-
When using the package
accounts-2fa
, use this to the size of the token sequence generated. The default is 6. - clientStorage 'session' or 'local'
-
By default login credentials are stored in local storage, setting this to true will switch to using session storage.
From Meteor 2.5 you can set these in your Meteor settings under Meteor.settings.packages.accounts-base
. Note that due to the nature of settings file you won’t be able to set parameters that require functions.
Register a callback to be called after a login attempt succeeds.
Arguments
- func Function
-
The callback to be called when login is successful. The callback receives a single object that holds login details. This object contains the login result type (password, resume, etc.) on both the client and server.
onLogin
callbacks registered on the server also receive extra data, such as user details, connection information, etc.
See description of AccountsCommon#onLoginFailure for details.
Register a callback to be called after a login attempt fails.
Arguments
- func Function
-
The callback to be called after the login has failed.
Either the onLogin
or the onLoginFailure
callbacks will be called
for each login attempt. The onLogin
callbacks are called after the
user has been successfully logged in. The onLoginFailure
callbacks are
called after a login attempt is denied.
These functions return an object with a single method, stop
. Calling
stop()
unregisters the callback.
On the server, the callbacks get a single argument, the same attempt info
object as validateLoginAttempt
. On the
client, the callback argument is an object containing a single error
property set to the Error
-object which was received from the failed login
attempt.
Register a callback to be called after a logout attempt succeeds.
Arguments
- func Function
-
The callback to be called when logout is successful.
On the server, the func
callback receives a single argument with the object below. On the
client, no arguments are passed.
- userObject
The Meteor user object of the user which just logged out.
- connectionObject
The
connection
object the request came in on. SeeMeteor.onConnection
for details.- collectionObject
The
collection
The name of the Mongo.Collection or the Mongo.Collection object to hold the users.
new AccountsClient(options)
Constructor for the Accounts
object on the client.
Options
- connection Object
-
Optional DDP connection to reuse.
- ddpUrl String
-
Optional URL for creating a new DDP connection.
- clientStorage 'session' or 'local'
-
Optional Define what kind of storage you want for credentials on the client. Default is 'local' to use
localStorage
. Set to 'session' to use session storage.
At most one of options.connection
and options.ddpUrl
should be
provided in any instantiation of AccountsClient
. If neither is provided,
Meteor.connection
will be used as the .connection
property of the
AccountsClient
instance.
Note that AccountsClient
is currently available only on the client, due
to its use of browser APIs such as window.localStorage
. In principle,
though, it might make sense to establish a client connection from one
server to another remote accounts server. Please let us
know
if you find yourself needing this server-to-server functionality.
These methods are defined on AccountsClient.prototype
, and are thus
available only on the client:
True if a login method (such as Meteor.loginWithPassword
, Meteor.loginWithFacebook
, or Accounts.createUser
) is currently in progress. A reactive data source.
Log the user out.
Arguments
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
Log out other clients logged in as the current user, but does not log out the client that calls this function.
Arguments
- callback Function
-
Optional callback. Called with no arguments on success, or with a single
Error
argument on failure.
new AccountsServer(server)
Constructor for the Accounts
namespace on the server.
Arguments
- server Object
-
A server object such as
Meteor.server
.
These methods are defined on AccountsServer.prototype
, and are thus
available only on the server:
Set restrictions on new user creation.
Arguments
- func Function
-
Called whenever a new user is created. Takes the new user object, and returns true to allow the creation or false to abort.
This can be called multiple times. If any of the functions return false
or
throw an error, the new user creation is aborted. To set a specific error
message (which will be displayed by accounts-ui
), throw a new
Meteor.Error
.
Example:
// 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';
});
If the user is being created as part of a login attempt from a client (eg,
calling Accounts.createUser
from the client, or
logging in for the first time with an external
service), these callbacks are called before
the Accounts.validateLoginAttempt
callbacks. If these callbacks succeed but those fail, the user will still be
created but the connection will not be logged in as that user.
Customize new user creation.
Arguments
- func Function
-
Called whenever a new user is created. Return the new user object, or throw an
Error
to abort the creation.
Use this when you need to do more than simply accept or reject new user creation. With this function you can programatically control the contents of new user documents.
The function you pass will be called with two arguments: options
and
user
. The options
argument comes
from Accounts.createUser
for
password-based users or from an external service login flow. options
may come
from an untrusted client so make sure to validate any values you read from
it. The user
argument is created on the server and contains a
proposed user object with all the automatically generated fields
required for the user to log in, including the _id
.
The function should return the user document (either the one passed in or a
newly-created object) with whatever modifications are desired. The returned
document is inserted directly into the Meteor.users
collection.
The default create user function simply copies options.profile
into
the new user document. Calling onCreateUser
overrides the default
hook. This can only be called once.
Example:
// 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;
});
Validate login attempts.
Arguments
- func Function
-
Called whenever a login is attempted (either successful or unsuccessful). A login can be aborted by returning a falsy value or throwing an exception.
Call validateLoginAttempt
with a callback to be called on login
attempts. It returns an object with a single method, stop
. Calling
stop()
unregisters the callback.
When a login attempt is made, the registered validate login callbacks are called with a single argument, the attempt info object:
- typeString
The service name, such as “password” or “twitter”.
- allowedBoolean
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).
- errorException
When
allowed
is false, the exception describing why the login failed. It will be aMeteor.Error
for failures reported to the user (such as invalid password), and can be a another kind of exception for internal errors.- userObject
When it is known which user was attempting to login, the Meteor user object. This will always be present for successful logins.
- connectionObject
The
connection
object the request came in on. SeeMeteor.onConnection
for details.- collectionObject
The
collection
The name of the Mongo.Collection or the Mongo.Collection object to hold the users.- methodNameString
The name of the Meteor method being used to login.
- methodArgumentsArray
An array of the arguments passed to the login method.
A validate login callback must return a truthy value for the login to
proceed. If the callback returns a falsy value or throws an
exception, the login is aborted. Throwing a Meteor.Error
will
report the error reason to the user.
All registered validate login callbacks are called, even if one of the callbacks
aborts the login. The later callbacks will see the allowed
field set to
false
since the login will now not be successful. This allows later callbacks
to override an error from a previous callback; for example, you could override
the “Incorrect password” error with a different message.
Validate login callbacks that aren’t explicitly trying to override a previous error generally have no need to run if the attempt has already been determined to fail, and should start with
if (!attempt.allowed) {
return false;
}
Validate login from external service
Arguments
- func Function
-
Called whenever login/user creation from external service is attempted. Login or user creation based on this login can be aborted by passing a falsy value or throwing an exception.
Use this hook if you need to validate that user from an external service should be allowed to login or create account.
- typeString
The service name, such as “google” or “twitter”.
- dataObject
Data retrieved from the service
- userObject
If user was found in the database that matches the criteria from the service, their data will be provided here.
You should return a Boolean
value, true
if the login/registration should
proceed or false
if it should terminate. In case of termination
the login attempt will throw an error 403
, with the message: Login forbidden
.
Customize user selection on external logins
Arguments
- func Function
-
Called whenever a user is logged in via oauth and a user is not found with the service id. Return the user or undefined.
When allowing your users to authenticate with an external service, the process will
eventually call Accounts.updateOrCreateUserFromExternalService
. By default, this
will search for a user with the service.<servicename>.id
, and if not found will
create a new user. As that is not always desirable, you can use this hook as an
escape hatch to look up a user with a different selector, probably by emails.address
or username
. Note the function will only be called if no user was found with the
service.<servicename>.id
selector.
The function will be called with a single argument, the info object:
- serviceNameString
The external service name, such as “google” or “twitter”.
- serviceDataObject
The data returned by the service oauth request.
- optionsException
An optional argument 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.
The function should return either a user document or undefined
. Returning a user
will result in the populating the service.<servicename>
in your user document,
while returning undefined
will result in a new user account being created.
If you would prefer that a new account not be created, you could throw an error
instead of returning.
Example:
// 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)
}
})
Registers a new login handler.
Arguments
- name String
-
The type of login method like oauth, password, etc.
- handler Function
-
A function that receives an options object (as passed as an argument to the
login
method) and returns one ofundefined
, meaning don't handle or a login method result object.
Use this to register your own custom authentication method. This is also used by all of the other inbuilt accounts packages to integrate with the accounts system.
There can be multiple login handlers that are registered. When a login request is made, it will go through all these handlers to find its own handler.
The registered handler callback is called with a single argument, the options
object which comes from the login method. For example, if you want to login with a plaintext password, options
could be { user: { username: <username> }, password: <password> }
,or { user: { email: <email> }, password: <password> }
.
The login handler should return undefined
if it’s not going to handle the login request or else the login result object.
Rate Limiting
By default, there are rules added to the DDPRateLimiter
that rate limit logins, new user registration and password reset calls to a
limit of 5 requests per 10 seconds per session. These are a basic solution
to dictionary attacks where a malicious user attempts to guess the passwords
of legitimate users by attempting all possible passwords.
These rate limiting rules can be removed by calling
Accounts.removeDefaultRateLimit()
. Please see the
DDPRateLimiter
docs for more information.
AccountsServer#addDefaultRateLimit()
Add a default rule of limiting logins, creating new users and password reset to 5 times every 10 seconds per connection.
AccountsServer#removeDefaultRateLimit()
Removes default rate limiting rule