v0.8
Auth
class Auth → file: core/lib/Auth.jsAuthentication with the JWT token and cookie.
Instance
The auth instance is created bynew Auth(authOpts)
.
Auth Properties
Property | Description | Type | Default |
---|---|---|---|
authOpts | The auth options (see table below). | object | {...} |
cookie | The lib/Cookie class instance. | object | {...} |
httpClient | The HTTPClient class instance. | object | {...} |
jwtToken | JWT token received after succesful login, for example: 'JWT aWqwada...' | string | |
loggedUser | The user object. Required fields: {username:string, password:string, role:string}. The role can be 'admin' for example. |
object | {} |
authOpts
Property | Description | Type | Default |
---|---|---|---|
apiLogin | API login url, for example: http://127.0.0.1:8001/users/login | string | |
afterGoodLogin | redirect after succesful login, for example '/{loggedUserRole}/dashboard' | string | |
afterBadLogin | redirect after unsuccesful login, for example '/login' | string | |
afterLogout | URL after logout() method is used, for example '/login' | string |
NOTICE: The parameter afterGoodLogin can contain {loggedUserRole}
which will be replaced with the user role.
For example /{loggedUserRole}/dashboard will be resolved to /admin/dashboard if the user's role is 'admin'.
Methods
Use this methods for the authentication and to guard specific routes from unauthorised access.
Use app.auth($auth)
to inject $auth in the controller property this.$auth, where $auth is Auth class instance.
async login(creds) :Promise<object>
Call API's URL defined by authOpts.apiLogin parameter.The returned value is the API response i.e. JS object:
On succesful login two cookies are created:
a) auth_jwtToken with value for example: 'JWT aWqra...'
b) auth_loggedUser with value of the user object which is returned by the API
-
ARGUMENTS:
- creds :object - credentials object sent as body to the API:
{username :string, password :string}
async logout(ms) :Promise<void>
Logout by deleting auth_jwtToken and auth_loggedUser cookies and redirect to afterLogout URL.-
ARGUMENTS:
- ms :number - the logout delay after the method logout is called
getLoggedUserInfo(ms) :object
Get logged user info returned from the API and saved in the auth_loggedUser cookie.getJWTtoken() :string
Get JWT token returned from the API and saved in the auth_jwtToken cookie.Auth Guards
There are also other methods which shouldn't be used in the controller but as the route guard options (route middleware functions).
- autoLogin() --Checks if user is logged and if yes do auto login e.g. redirect to afterGoodLogin URL.
Use route guard option: ['when' '/login' 'LoginCtrl', {autoLogin: true}]
- isLogged() --Checks if user is logged and if not redirect to afterBadLogin URL.
Use route guard option: ['when' '/admin/product/:id' 'AdminProductCtrl', {isLogged: true, hasRole: true}]
- hasRole() --Checks if logged user has required role: 'admin', 'customer'...etc which corresponds to the URL. For example role "admin" must have URL starts with /admin/.
Use route guard option: ['when' '/admin/product/:id' 'AdminProductCtrl', {isLogged: true, hasRole: true}]
First define lib/auth.js
import { corelib } from '@mikosoft/dodo';
const env = import .meta.env;
const baseURL = env.DODO_API_baseURL;
const authOpts = {
apiLogin: `${baseURL}/panel/users/login`,
afterGoodLogin: '/{loggedUserRole}/dashboard', // redirect after succesful login:
afterBadLogin: '/', // redirect after unsuccesful login
afterLogout: '/' // URL after logout
};
const auth = new corelib.Auth(authOpts);
export default auth;
After that edit app.js and inject auth.
import auth from '/lib/auth.js';
import $routes from '/routes.js';
const app = new App('myApp');
app
.auth(auth)
.httpClient($httpClient)
.fridge('wsLib', wsLib)
.preflight($preflight)
.postflight($postflight)
.debug($debugOpts);
app
.routes($routes)
.listen();
And finally add login() method in the LoginCtrl.js controller
LoginCtrl.js
---------------------------
export class LoginCtrl extends Controller {
async tryLogin() {
try {
const username = this.username;
const password = this.password;
await this.$auth.login({ username, password });
} catch (err) {
popups.notify(err.message, 'inverse');
console.error(err);
}
}
}
views/pages/login.html
---------------------------
<form>
username: <input type="text" name="username" dd-set="username">
password: <input type="text" name="password" dd-set="password">
<button dd-click="tryLogin()">Login</button>
</form>
Don't forget to use auth grads in route definitions i.e. routes.js file:
import LoginCtrl from '/controllers/LoginCtrl.js';
import DashboardCtrl from '/controllers/DashboardCtrl.js';
import auth from '/lib/auth.js';
// auth gurads
const autoLogin = auth.autoLogin.bind(auth);
const isLogged = auth.isLogged.bind(auth);
const hasRole = auth.hasRole.bind(auth);
const $routes = [
['when', '/', LoginCtrl, { authGuards: [autoLogin] }],
['when', '/developer/dashboard', DeveloperDashboardCtrl, { authGuards: [isLogged, hasRole] }],
];
export default $routes;
The server API response after succesful login;
{
"success": true,
"message": "Login was successful. JWT is generated and you can use it in API request header. Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjYwOWY3NGI5Y2Y0NDE5MGEyZDIzN2E2YiIsInVzZXJuYW1lIjoiZGV2YSIsImlhdCI6MTY5MDAyMDE0Mn0.uqGjSwq8Nox-BeNEm-nNi_4Ab03ThOQTlPd3-VBu3QM",
"jwtToken": "JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkqYVCJ9.eyJpZCI6IjYwOWY3NGI5Y2Y0NDE5MGEyZDIzN2E2YiIsInVHHXJuYW1lIjoiZGV2YSIsImlhdCI6MTY5MDAyMDE0Mn0.uqGjSwq8Nox-BeNEm-nNi_4Ab03ThOQTlPd3-VBu3QM",
"loggedUser": {
"role": "developer",
"is_active": true,
"login_counter": 52,
"connected": false,
"_id": "609f74b9cf44190a2d237a6b",
"first_name": "Deva",
"last_name": "Dev",
"address": "Roki street 33",
"city": "NY",
"country": "USA",
"email": "deva@test.com",
"website": "www.deva.com",
"phone": "+1 111222333",
"misc": null,
"username": "deva",
"password": "--removed--",
"created_at": "2021-05-15T07:14:01.280Z",
"updated_at": "2023-07-20T09:24:24.180Z",
"__v": 0,
"login_last": "2023-07-20T09:12:53.118Z",
"login_last_ip": "93.139.0.224",
"ip": "",
"port": null,
"socketId": ""
}
}
}
Stackblitz Examples
- Auth - test login, logout and route gurads: autoLogin, isLogged, hasRole