The "auth" provides basic authentication functionality including a User model, authentication routes, middleware to extract logged in users, and methods relating to authentication.
The "auth" service provides some methods many of which are designed for use
by the route handlers. Many methods return an object containing a boolean
success and a string message, and sometimes also a User model instance.
async registerUser(username, password, email=null)
This method takes the given information and attempts to register
the given user. It will return success and message. If success
is true, the newly created and saved User instance is also returned as
user.
async someFunction() {
let { success, message, user } = await App.$auth.registerUser("new_user",
"password123");
if (success) {
// do something with user
} else {
console.error(message);
}
}
async loginByUsernameAndPassword(username, password)
This method will check if the username/password combination matches an
existing user. It returns success, message, and, if successful, the User
instance for that user.
let { success, user } = await App.$auth.loginByUsernameAndPassword('admin',
'password123');
async verifyUserByToken(username, token)
This method will check if the given username has the matching verification
token and, if so, saves that user as verified. It returns success, message,
and, if successful, the User
instance for that user.
async resetVerification(username)
This method will reset the verification token of the matching user with a
newly generated token. It returns success, message,
and, if successful, the User
instance for that user.
async verifyUser(username)
This method looks up the matching user and marks it verified, overriding
the token process. It returns success, message,
and, if successful, the User
instance for that user.
There are two methods for setting a user's password. The first one if for when you don't have the existing user object on hand.
async setPassword(username, password)
This method sets the matching user's password to the given password.
It returns success, message,
and, if successful, the User
instance for that user.
async setUserPassword(user, password)
This method takes a user instance and changes its password to the given password. It saves and returns the user.
async forgotPassword(email)
This method searches for a user with the matching e-mail address and, if found,
gives it a forgotten password token. It returns success, message,
and, if successful, the User
instance for that user.
async checkForgotToken(username, token)
This method will check if the given username has the matching password reset
token. It returns success, message,
and, if successful, the User
instance for that user.
The "auth" service defines two methods to quickly get full links based on users and tokens.
getVerifyLink({ username, verifyToken })
getResetLink({ username, forgotToken })
These two methods do not validate that those tokens are valid for that username. They simply return what the full links would be if they were valid. Because the necessary values are destructured, you could pass a User object to these methods:
async someFunction() {
const adminUser = await App.$db.model('User').findOne({
username: 'admin' }).exec();
let adminVerifyLink = App.$auth.getVerifyLink(adminUser);
let adminResetPasswordLink = App.$auth.getResetLink(adminUser);
}
This is the default configuration for the "auth" app:
module.exports = {
usernameRegex: /^[a-zA-Z0-9][a-zA-Z0-9\_]{4,23}$/,
usernameDescription: "Username must have only letters, numbers, and underscores and 5-24 characters.",
passwordRegex: /^[a-zA-Z0-9][a-zA-Z0-9\_]{4,23}$/,
passwordDescription: "Password must have only letters, numbers, and underscores and 5-24 characters.",
requireEmail: true,
sendVerifyLink: true,
authEmailFrom: process.env.WEBMASTER_EMAIL || 'auth@example.com',
verifyExpirationHours: 48,
};
The first 4 properties define username and password requirements as well as the description messages that will be shown to users when validation fails.
The requireEmail property determines whether or not e-mail addresses are
required for account registration. If the sendVerifyLink property is true,
then verification links will be e-mailed to new account users. Those e-mails
(as well as password reset e-mails) wil be sent from the value of
authEmailFrom. Both password reset tokens and account verification tokens
are valid for the number of hours specified by verifyExpirationHours.
You can create a new user with admin privileges with the following command:
node . auth create-admin-user [username=admin] [password]
This will register a new user with the given information. If no username is provided, the username will be "admin". If no password is provided, a random password is generated and displayed.
The "auth" app can publish config, source, and templates files into the project directory:
node . publish --config --src --templates auth
The config file will go to config/auth.js, and its values are documented
above.
The source file directory will go to src/auth and it contains a component
for the admin panel.
The templates will go to templates/auth and are used by the authentication
routes. Feel free to edit the pages, but try to leave the key functionality
(form input names, links, etc) intact.
The User model is accessible from the "db" service:
const User = App.$db.model('User');
The User model schema has the following attributes:
| Attribute | Type | Description |
|---|---|---|
username |
String | The username. |
emailAddress |
String | The e-mail address. |
password |
String | The hashed password. |
isAdmin |
Boolean | Whether or not the user has admin privileges. |
isVerified |
Boolean | Whether or not the account has been verified. |
verifyToken |
String | The verification token. |
verifyExpiry |
Date | The expiration date of the verification token. |
forgotToken |
String | The reset password token. |
forgotExpiry |
Date | The expiration date of the reset password token. |
The "auth" app defines the following named middleware which you can add to routes and access via the "middleware" app.
req.user.req.user is not defined, a redirect response is set to the login page with the next parameter set to the original destination.To add the authentication routes, mount the "auth" app somewhere in the
"urls" property of config/routes.js (preferably at "/auth").
Requests for "/" (at whatever mount point) will be redirected to the login page unless a user is logged in, in which case they will be redirected to the profile page.
The "auth" router has pages for login, registration, etc. You can direct
users to /<mount_point>/login?next=/other/page to have them redirected
after logging instead of going to the profile page.