Accounts

Documentation of how to use Meteor's accounts functionality.

The Meteor Accounts system builds on top of the userId support inpublish and methods. The corepackages add the concept of user documents stored in the database, andadditional packages add secure passwordauthentication, integration with third partylogin services, and a pre-built userinterface.

The basic Accounts system is in the accounts-base package, butapplications typically include this automatically by adding one of thelogin provider packages: accounts-password, accounts-facebook,accounts-github, accounts-google, accounts-meetup,accounts-twitter, or accounts-weibo.

Read more about customizing user accounts in the Accounts article in the Meteor Guide.

Anywhere but publish functions

Meteor.user()

import { Meteor } from 'meteor/meteor' (accounts-base/accounts_common.js, line 311)

Get the current user record, or null if no user is logged in. A reactive data source.

Retrieves the user record for the current user fromthe Meteor.users collection.

On the client, this will be the subset of the fields in the document thatare published from the server (other fields won’t be available on theclient). By default the server publishes username, emails, andprofile (writable by user). See Meteor.users for more onthe fields used in user documents.

On the server, this will fetch the record from the database. To improve thelatency of a method that uses the user document multiple times, save thereturned record to a variable instead of re-calling Meteor.user().

Anywhere but publish functions

Meteor.userId()

import { Meteor } from 'meteor/meteor' (accounts-base/accounts_common.js, line 304)

Get the current user id, or null if no user is logged in. A reactive data source.

Anywhere

Meteor.users

import { Meteor } from 'meteor/meteor' (accounts-base/server_main.js, line 19)

A Mongo.Collection containing user documents.

This collection contains one document per registered user. Here’s an exampleuser document:

  1. {
  2. _id: 'QwkSmTCZiw5KDx3L6', // Meteor.userId()
  3. username: 'cool_kid_13', // Unique name
  4. emails: [
  5. // Each email address can only belong to one user.
  6. { address: 'cool@example.com', verified: true },
  7. { address: 'another@different.com', verified: false }
  8. ],
  9. createdAt: new Date('Wed Aug 21 2013 15:16:52 GMT-0700 (PDT)'),
  10. profile: {
  11. // The profile is writable by the user by default.
  12. name: 'Joe Schmoe'
  13. },
  14. services: {
  15. facebook: {
  16. id: '709050', // Facebook ID
  17. accessToken: 'AAACCgdX7G2...AbV9AZDZD'
  18. },
  19. resume: {
  20. loginTokens: [
  21. { token: '97e8c205-c7e4-47c9-9bea-8e2ccc0694cd',
  22. when: 1349761684048 }
  23. ]
  24. }
  25. }
  26. }

A user document can contain any data you want to store about a user. Meteortreats the following fields specially:

  • username: a unique String identifying the user.
  • emails: an Array of Objects with keys address and verified;an email address may belong to at most one user. verified isa Boolean which is true if the user has verified theaddress with a token sent over email.
  • createdAt: the Date at which the user document was created.
  • profile: an Object which the user can create and update with any data.Do not store anything on profile that you wouldn’t want the user to editunless you have a deny rule on the Meteor.users collection.
  • services: an Object containing data used by particularlogin services. For example, its reset field containstokens used by forgot password links,and its resume field contains tokens used to keep youlogged in between sessions.

Like all Mongo.Collections, you can access alldocuments on the server, but only those specifically published by the server areavailable on the client. You can also use all Collection methods, for instanceMeteor.users.remove on the server to delete a user.

By default, the current user’s username, emails and profile arepublished to the client. You can publish additional fields for thecurrent user with:

  1. // Server
  2. Meteor.publish('userData', function () {
  3. if (this.userId) {
  4. return Meteor.users.find({ _id: this.userId }, {
  5. fields: { other: 1, things: 1 }
  6. });
  7. } else {
  8. this.ready();
  9. }
  10. });
  11. // Client
  12. Meteor.subscribe('userData');

If the autopublish package is installed, information about all userson the system is published to all clients. This includes username,profile, and any fields in services that are meant to be public(eg services.facebook.id,services.twitter.screenName). Additionally, when using autopublishmore information is published for the currently logged in user,including access tokens. This allows making API calls directly fromthe client for services that allow this.

Users are by default allowed to specify their own profile field withAccounts.createUser and modify it withMeteor.users.update. To allow users to edit additional fields, useMeteor.users.allow. To forbid users from making any modifications totheir user document:

  1. Meteor.users.deny({ update: () => true });

Client

Meteor.loggingIn()

import { Meteor } from 'meteor/meteor' (accounts-base/accounts_client.js, line 740)

True if a login method (such as Meteor.loginWithPassword, Meteor.loginWithFacebook, or Accounts.createUser) is currently in progress. A reactive data source.

For example, the accounts-ui package uses this to display ananimation while the login request is being processed.

Client

Meteor.logout([callback])

import { Meteor } from 'meteor/meteor' (accounts-base/accounts_client.js, line 756)

Log the user out.

Arguments

  • callbackFunction
  • Optional callback. Called with no arguments on success, or with a single Error argument on failure.

Client

Meteor.logoutOtherClients([callback])

import { Meteor } from 'meteor/meteor' (accounts-base/accounts_client.js, line 764)

Log out other clients logged in as the current user, but does not log out the client that calls this function.

Arguments

  • callbackFunction
  • Optional callback. Called with no arguments on success, or with a single Error argument on failure.

For example, when called in a user’s browser, connections in that browserremain logged in, but any other browsers or DDP clients logged in as that userwill be logged out.

Client

Meteor.loginWithPassword(user, password, [callback])

import { Meteor } from 'meteor/meteor' (accounts-password/password_client.js, line 33)

Log the user in with a password.

Arguments

  • userObject or String
  • Either a string interpreted as a username or an email; or an object with a single key: email, username or id. Username or email match in a case insensitive manner.

  • passwordString

  • The user's password.

  • callbackFunction

  • Optional callback. Called with no arguments on success, or with a single Error argument on failure.

If there are multiple users with a username or email only differing in case, a case sensitive match is required. Although createUser won’t let you create users with ambiguous usernames or emails, this could happen with existing databases or if you modify the users collection directly.

This method can fail throwing one of the following errors:

  • “Unrecognized options for login request [400]” if user or password is undefined.
  • “Match failed [400]” if user isn’t an Object or String, or password isn’t a String.
  • “User not found [403]” if the email or username provided in user doesn’t belong to a registered user.
  • “Incorrect password [403]” if the password provided is incorrect.
  • “User has no password set [403]” if user doesn’t have a password.

This function is provided by the accounts-password package. See thePasswords section below.

Client

Meteor.loginWith<ExternalService>([options], [callback])

import { Meteor } from 'meteor/meteor' (accounts-oauth/oauth_client.js, line 3)

Log the user in using an external service.

Arguments

  • callbackFunction
  • Optional callback. Called with no arguments on success, or with a single Error argument on failure. The callback cannot be called if you are using the "redirect" loginStyle, because the app will have reloaded in the meantime; try using client-side login hooks instead.

Options

  • requestPermissionsArray of Strings
  • A list of permissions to request from the user.

  • requestOfflineTokenBoolean

  • If true, asks the user for permission to act on their behalf when offline. This stores an additional offline token in the services field of the user document. Currently only supported with Google.

  • loginUrlParametersObject

  • Provide additional parameters to the authentication URI. Currently only supported with Google. See Google Identity Platform documentation.

  • loginHintString

  • An email address that the external service will use to pre-fill the login prompt. Currently only supported with Meteor developer accounts and Google accounts. If used with Google, the Google User ID can also be passed.

  • loginStyleString

  • Login style ("popup" or "redirect", defaults to the login service configuration). The "popup" style opens the login page in a separate popup window, which is generally preferred because the Meteor application doesn't need to be reloaded. The "redirect" style redirects the Meteor application's window to the login page, and the login service provider redirects back to the Meteor application which is then reloaded. The "redirect" style can be used in situations where a popup window can't be opened, such as in a mobile UIWebView. The "redirect" style however relies on session storage which isn't available in Safari private mode, so the "popup" style will be forced if session storage can't be used.

  • redirectUrlString

  • If using "redirect" login style, the user will be returned to this URL after authorisation has been completed.

Available functions are:

These functions initiate the login process with an externalservice (eg: Facebook, Google, etc), using OAuth. When called they open a new pop-upwindow that loads the provider’s login page. Once the user has logged inwith the provider, the pop-up window is closed and the Meteor clientlogs in to the Meteor server with the information provided by the externalservice.

Requesting Permissions

In addition to identifying the user to your application, some serviceshave APIs that allow you to take action on behalf of the user. Torequest specific permissions from the user, pass therequestPermissions option the login function. This will cause the userto be presented with an additional page in the pop-up dialog to permitaccess to their data. The user’s accessToken — with permissionsto access the service’s API — is stored in the services field ofthe user document. The supported values for requestPermissions differfor each login service and are documented on their respective developersites:

External login services typically require registering and configuringyour application before use. The easiest way to do this is with theaccounts-ui package which presents a step-by-step guideto configuring each service. However, the data can be also be enteredmanually in the ServiceConfiguration.configurations collection, whichis exported by the service-configuration package.

Configuring Services

First, add the service configuration package:

  1. meteor add service-configuration

Then, in your app (this example is for the Weebo service):

  1. ServiceConfiguration.configurations.upsert(
  2. { service: 'weibo' },
  3. {
  4. $set: {
  5. loginStyle: "popup",
  6. clientId: "1292962797", // See table below for correct property name!
  7. secret: "75a730b58f5691de5522789070c319bc"
  8. }
  9. }
  10. );

The correct property name to use for the API identifier (i.e. clientId in the above example) depends on the the login service being used, so be sure to use the correct one:

Property NameServices
appIdFacebook
clientIdGithub, Google, Meetup, Meteor Developer Accounts, Weibo
consumerKeyTwitter

Additionally, each external service has its own login provider package and login function. Forexample, to support GitHub login, run the following in your terminal:

  1. meteor add accounts-github

and use the Meteor.loginWithGithub function:

  1. Meteor.loginWithGithub({
  2. requestPermissions: ['user', 'public_repo']
  3. }, (error) => {
  4. if (error) {
  5. Session.set('errorMessage', error.reason || 'Unknown error');
  6. }
  7. });

Login service configuration is sent from the server to the client over DDP whenyour app starts up; you may not call the login function until the configurationis loaded. The function Accounts.loginServicesConfigured() is a reactive datasource that will return true once the login service is configured; you shouldnot make login buttons visible or active until it is true.

Ensure that your $ROOT_URL matches the authorizeddomain and callback URL that you configure with the external service (forinstance, if you are running Meteor behind a proxy server, $ROOT_URL should bethe externally-accessible URL, not the URL inside your proxy).

Manual settings configuration

You can use Accounts.loginServiceConfiguration to view and edit the settings collection:

  1. Accounts.loginServiceConfiguration.find();

Popup versus redirect flow

When configuring OAuth login with a provider (such as Facebook or Google), Meteor lets you choose a popup- or redirect-based flow. In a popup-based flow, when a user logs in, they will be prompted to login at the provider in a popup window. In a redirect-based flow, the user’s whole browser window will be redirected to the login provider, and the window will redirect back to your app when the login is completed.

You can also pick which type of login to do by passing an option to Meteor.loginWith<ExternalService>

Usually, the popup-based flow is preferable because the user will not have to reload your whole app at the end of the login flow. However, the popup-based flow requires browser features such as window.close and window.opener that are not available in all mobile environments. In particular, we recommend using Meteor.loginWith<ExternalService>({ loginStyle: 'redirect' }) in the following environments:

  • Inside UIWebViews (when your app is loaded inside a mobile app)
  • In Safari on iOS8 (window.close is not supported due to a bug)

{{ currentUser }}

(accounts-base/accounts_client.js, line 787)

Calls Meteor.user(). Use {{#if currentUser}} to check whether the user is logged in.

{{ loggingIn }}

(accounts-base/accounts_client.js, line 795)

Calls Meteor.loggingIn().

Client

Accounts.ui.config(options)

import { Accounts } from 'meteor/accounts-base' (accounts-ui-unstyled/accounts_ui.js, line 41)

Configure the behavior of {{> loginButtons}}.

Options

  • requestPermissionsObject
  • Which permissions to request from the user for each external service.

  • requestOfflineTokenObject

  • To ask the user for permission to act on their behalf when offline, map the relevant external service to true. Currently only supported with Google. See Meteor.loginWithExternalService for more details.

  • forceApprovalPromptObject

  • If true, forces the user to approve the app's permissions, even if previously approved. Currently only supported with Google.

  • passwordSignupFieldsString

  • Which fields to display in the user creation form. One of 'USERNAME_AND_EMAIL', 'USERNAME_AND_OPTIONAL_EMAIL', 'USERNAME_ONLY', or 'EMAIL_ONLY' (default).

Example:

  1. Accounts.ui.config({
  2. requestPermissions: {
  3. facebook: ['user_likes'],
  4. github: ['user', 'repo']
  5. },
  6. requestOfflineToken: {
  7. google: true
  8. },
  9. passwordSignupFields: 'USERNAME_AND_OPTIONAL_EMAIL'
  10. });