# Authentication

# Introduction

ExpressWebJs strives to give you the tools you need to implement authentication quickly, securely, and easily. Since ExpressWebJs does not support session state, incoming requests that you wish to authenticate will be authenticated via a stateless mechanism such as API tokens.

# Password Hashing

ExpressWebJs uses the Hash module to verify passwords.

Always hash your passwords before saving them to the database.

# Getting Started

Run the Maker command to setup your auth routes in Routes/authRoute/index.ts file

Here is our generated authentication route endpoints

import { Route } from "Elucidate/Route/manager";

/*
|--------------------------------------------------------------------------
| Authentication Route File   
|--------------------------------------------------------------------------
|
| This route handles both login and registration.
| 
*/

Route.post("/register", "Auth/RegisterController@register");

Route.post("/login", "Auth/LoginController@login");

export default Route.exec;

Next, we need to uncomment the auth middleware inside the App/Http/kernel.ts file in the routeMiddleware section:

   /*
  |--------------------------------------------------------------------------
  | Route Middleware
  |--------------------------------------------------------------------------
  |
  | Route middleware is a key/value object to conditionally add middleware on
  | specific routes or assigned to group of routes.
  |
  | // define
  | {
  |   auth: 'App/Http/Middleware/Auth'
  | }
  |
  | // in your route add ["auth"]
  |
  */
  routeMiddleware: {
    auth: "App/Http/Middleware/Auth",
  },

# Configuration

Authentication configuration is saved inside the App/Config/Auth.ts file

module.exports = {
  /*
  |--------------------------------------------------------------------------
  | Authenticator
  |--------------------------------------------------------------------------
  |
  | ExpressWebJs does not support session state, incoming requests 
  | that you wish to authenticate must be authenticated via a
  | stateless mechanism such as API tokens.
  |
  */
  authenticator: "jwt",

  /*
  |--------------------------------------------------------------------------
  | Jwt
  |--------------------------------------------------------------------------
  |
  | The jwt authenticator works by passing a jwt token on each HTTP
  | request via HTTP `Authorization` header.
  |
  */
  jwt: {
    model: "UserModel",
    driver: "jwt",
    uid: "email",
    password: "password",
    secret: process.env.APP_KEY,
    options: {
      expiresIn: 86400, //default is 86400 (24 hrs)
    },
  },
};
Key Value Description
uid Database field name Database field used as the unique identifier for a given user.
password Database field name Field used to verify the user password.
model Model name Model used to query the database
secret APP_KEY Application key. This is located in your .env file
expiresIn Valid time in seconds or ms string When to expire tokens. (This is in the options section)
algorithm HS256, HS384, RS256 Algorithm used to generate tokens. (This is in the options section)

You can add more JWT options in the options sections.

By default, uid and password values are set to email and password. If you want to change it to any other column name, you can do that like so:

⚠️ Note: make sure the column names exists in your table.

Lets change uid from email to username, that means we want to authenticate with username and password instead of email and password.

jwt: {
    model: "UserModel",
    driver: "jwt",
    uid: "username",
    password: "password",
    secret: process.env.APP_KEY,
    options: {
      expiresIn: 86400, //default is 86400 (24 hrs)
    },
};

Then update the validator values for LoginController

LoginValidation is in App/Http/Controller/Requests/LoginValidation.ts

import FormRequest from "Elucidate/Validator/FormRequest";

type dataType = { email: string; password: string };

class LoginValidation extends FormRequest {
  /**
   * Handle login request validation.
   * @param {*} data | e.g request body
   */
  static async validate<T>(data: T) {
    return await FormRequest.make<T>(data, {
      email: "required|string|email|max:255",
      password: "required|string|min:8",
    });
  }
}

export { LoginValidation, dataType };