Node JS — Authentication and Authorization With Admin Bro

Sjlouji
The Startup
Published in
5 min readSep 16, 2020
Cover Image

In this blog, I am explaining how to create a basic role-based authentication with Admin Bro. In my previous blog, I have explained what is Admin Bro and how to set up. Do visit it to know how to configure Admin Bro.

  1. Introduction

First of all, create a new Node and express application. After creating it, just install Admin bro to the project.

npm install admin-bro @admin-bro/express
npm install express-formidable
npm install @admin-bro/mongoose
npm i mongoose

The above commands install admin bro and other required dependencies to make Admin bro work.

Now let’s start configuring our application with Admin Bro. I have created a simple setup below. Copy and paste it to your workspace.

index.js

var express = require('express');
const Emp = require('./Models/emp')
const AdminBro = require('admin-bro')
const AdminBroMongoose = require('@admin-bro/mongoose')
const AdminBroExpress = require('@admin-bro/express')
var app = express();
const mongoose = require('mongoose');//Routes
app.get('/', function (req, res) {
res.send('Hello World!');
});
//Database
mongoose.connect('mongodb://localhost/test', {useNewUrlParser: true});
mongoose.connection.once('open',function(){
console.log('Database connected Successfully');
}).on('error',function(err){
console.log('Error', err);
})
//Admin Bro
AdminBro.registerAdapter(AdminBroMongoose)
const AdminBroOptions = {
resources: [Emp],
}
const adminBro = new AdminBro(AdminBroOptions)
const router = AdminBroExpress.buildRouter(adminBro)
app.use(adminBro.options.rootPath, router)
app.listen(8000, function () {
console.log('Listening to Port 8000');
});

Models/emp.js

const mongoose = require('mongoose');
const empSchema = new mongoose.Schema({
empName: {
type: String,
required: true,
}, empEmail: {
type: String,
required: true,
},
})
module.exports = mongoose.model('Emp',empSchema)

After configuring, run the server and navigate to http://localhost:8000/admin. You will see an admin panel like the below one.

Default Admin Pannel of Admin Bro

2. Creating a User Model

Now let’s move to the auth section. To do that, let’s first create a new User Model. The user model that I have created has email, password, and role fields where the role field can take only two values either admin or member.

const mongoose = require('mongoose');const UserSchema = new mongoose.Schema({
email: {
type: String,
required: true,
},
encryptedPassword: {
type: String,
required: true,
},
role: {
type: String,
enum: ['admin', 'member'],
required: true
}
})
module.exports = mongoose.model('User',UserSchema)

After creating the model file, add our User model to Admin Bro.

index.js

const User = require('../Models/User')//Add Just the User Model to the AdminBroOptions
const AdminBroOptions = {
resources: [User, Emp],
}

On navigating to http://localhost:8000/admin, you should see the User model, generated in the left sidebar.

3. Authenticate Users

After registering the User model to Admin bro, run the below commands in the terminal which installs admin-bro-express and express-sessions.

npm i admin-bro-expressjs
npm i express-session

a. admin-bro-express — For integrating Admin Bro automatically to express.

b. express-session — Creating sessions with Express.

Now copy the below code to your file. The below code authenticates and validates the users.

index.js

const canModifyUsers = ({ currentAdmin }) => currentAdmin && currentAdmin.role === 'admin'AdminBro.registerAdapter(AdminBroMongoose)const AdminBroOptions = {
resources:
[Emp,{
resource: User,
options: {
properties: {
encryptedPassword: { isVisible: false },
password: {
type: 'string',
isVisible: {
list: false, edit: true, filter: false, show: false,
},
},
},
actions: {
new: {
before: async (request) => {
if(request.payload.record.password) {
request.payload.record = {
...request.payload.record,
encryptedPassword: await bcrypt.hash(request.payload.record.password, 10),
password: undefined,
}
}
return request
},
},
edit: { isAccessible: canModifyUsers },
delete: { isAccessible: canModifyUsers },
new: { isAccessible: canModifyUsers },

}
}
}],
}
const adminBro = new AdminBro(AdminBroOptions)
const router = AdminBroExpressjs.buildAuthenticatedRouter(adminBro, {
authenticate: async (email, password) => {
const user = await User.findOne({ email })
if (user) {
if (password === user.encryptedPassword) {
return user
}
}
return false
},
cookiePassword: 'session Key',
})

The code has two sections, where the first one checks if the user has permission the make CRUD operations on the particular model. The next one authenticates the user.

Now navigate to the http://localhost:8000/admin. It will redirect you automatically to http://localhost:8000/admin/login.

Login Page

4. Restricting Views

Restricting views is similar to what we did above. To authenticate if the user is admin, create a new function canEditEmp that checks the role of the user every time when called.

index.js

const canEditEmp = ({ currentAdmin, record }) => {
return currentAdmin && (
currentAdmin.role === 'admin'
)
}

After creating, copy the below code and paste it to your file.

index.js

const AdminBroOptions = {
resources:
[{
resource: Emp,
options: {
properties: {
ownerId: { isVisible: { edit: false, show: true, list: true, filter: true } }
},
actions: {
edit: { isAccessible: canEditEmp },
delete: { isAccessible: canEditEmp },
new: { isAccessible: canEditEmp },
}
}},

{
resource: User,
options: {
properties: {
encryptedPassword: { isVisible: false },
password: {
type: 'string',
isVisible: {
list: false, edit: true, filter: false, show: false,
},
},
},
actions: {
new: {
before: async (request) => {
if(request.payload.record.password) {
request.payload.record = {
...request.payload.record,
encryptedPassword: await bcrypt.hash(request.payload.record.password, 10),
password: undefined,
}
}
return request
},
},
edit: { isAccessible: canModifyUsers },
delete: { isAccessible: canModifyUsers },
new: { isAccessible: canModifyUsers },
}
}
}],
}

Log in to the Admin panel as a member. Now the Emp model will be displayed but you can't perform any operations on that table.

Member Login

Similarly, login as Admin user. Now you can perform all the CRUD operations.

Admin Login

Also, check my previous blog wherein I have explained how to setup Admin Bro with Node JS.

Feel free to contact me for any queries.

Email: sjlouji10@gmail.com

Linkedin: https://www.linkedin.com/in/sjlouji/

Complete code on my GitHub:

Happy coding…

--

--

Sjlouji
The Startup

Software Engineer at @Pando. Developer | Writer. From ABC to the world of code.