Authenticatie en autorisatie
Installeer bcrypt
npm install bcrypt
Installeer cookie-parser
npm install cookie-parser
Installeer jsonwebtoken
npm install jsonwebtoken
app.use(cookieParser());
import cookieParser from "cookie-parser";
Code-snippet op de volgende slide! -->
import Role from "../models/Role.js";
export const register = async (req, res) => {
const inputs = [
{ name: "firstname", label: "Voornaam", type: "text" },
{ name: "lastname", label: "Achternaam", type: "text" },
{ name: "email", label: "E-mail", type: "text" },
{ name: "password", label: "Password", type: "password" },
];
const roles = await Role.query();
res.render("register", {
layout: "layouts/authentication",
inputs,
roles,
});
}
Resultaat in browser, volgende slide -->
Authenticatie en autorisatie
import { body } from 'express-validator';
export default [
body("firstname").notEmpty().withMessage("Voornaam is een verplicht veld."),
body("lastname").notEmpty().withMessage("Achternaam is een verplicht veld."),
body("email")
.notEmpty()
.withMessage("E-mail is een verplicht veld.")
.bail()
.isEmail()
.withMessage("Onjuist e-mail adres"),
body("password")
.isLength({ min: 6 })
.withMessage("Wachtwoord moet bestaan uit minstens zes tekens."),
body("role").notEmpty().withMessage("De gebruiker heeft een rol nodig."),
];
app.post(
"/register",
AuthRegisterValidation,
AuthController.postRegister,
AuthController.register
);
import AuthRegisterValidation from "./middleware/validation/AuthRegisterValidation.js";
export const postRegister = async (req, res, next) => {
try {
const errors = validationResult(req);
// if we have validation errors
if (!errors.isEmpty()) {
console.log("We\'ve got some errors, dude...");
}
} catch(e) {
next(e.message);
}
};
app.post(
"/register",
AuthRegisterValidation,
AuthController.postRegister,
AuthController.register
);
if (!errors.isEmpty()) {
// set the form error fields
req.formErrorFields = {};
errors.array().forEach((error) => {
req.formErrorFields[error.path] = error.msg;
});
// set the flash message
req.flash = {
type: "danger",
message: "Er zijn fouten opgetreden",
};
return next();
}
export const register = async (req, res) => {
// input fields
const inputs = [
{
name: "firstname",
label: "Voornaam",
type: "text",
value: req.body?.firstname ? req.body.firstname : "",
err: req.formErrorFields?.firstname ? req.formErrorFields.firstname : "",
},
{
name: "lastname",
label: "Achternaam",
type: "text",
value: req.body?.lastname ? req.body.lastname : "",
err: req.formErrorFields?.lastname ? req.formErrorFields.lastname : "",
},
{
name: "email",
label: "E-mail",
type: "text",
value: req.body?.email ? req.body.email : "",
err: req.formErrorFields?.email ? req.formErrorFields.email : "",
},
{
name: "password",
label: "Password",
type: "password",
value: req.body?.password ? req.body.password : "",
err: req.formErrorFields?.password ? req.formErrorFields.password : "",
},
];
// get the roles
const roles = await Role.query();
const flash = req.flash || {};
// render the register page
res.render("register", {
layout: "layouts/authentication",
inputs,
roles,
flash,
});
};
[...]
else {
const user = await User.query().findOne({ email: req.body.email });
const role = await Role.query().findOne({ id: req.body.role });
// validate if the role exists in the database
if (!role) {
req.flash = { type: "danger", message: "Deze rol bestaat niet." };
req.formErrorFields = { role: "Deze rol bestaat niet." };
return next();
}
// validate if the user already exists
if (user) {
req.flash = { type: "danger", message: "Dit e-mail adres is al in gebruik." };
req.formErrorFields = { email: "Dit e-mail adres is al in gebruik." };
return next();
}
// temp res.send
res.send('no errors, registrate the user')
}
[...]
Authenticatie en autorisatie
Hashing refers to the process of generating a fixed-size output from an input of variable size using the mathematical formulas known as hash functions. This technique determines an index or location for the storage of an item in a data structure.
Hashing turns plain text into a unique code, which can't be reverted into a readable form
const hashedPassword = bcrypt.hash("geheim123", 10);
import bcrypt from "bcrypt";
export const postRegister = async (req, res, next) => {
[...]
const hashedPassword = bcrypt.hashSync(req.body.password, 10);
await User.query().insert({
firstname: req.body.firstname,
lastname: req.body.lastname,
email: req.body.email,
password: hashedPassword,
role_id: parseInt(req.body.role),
});
res.redirect("/login");
};
// Load hash from your password DB.
const isPassCorrect = bcrypt.compare("secret789", hash);
// --> false
// // Load hash from your password DB.
const isOtherPassCorrect = bcrypt.compare("geheim123", hash);
// --> true
Validatie, authenticatie en autorisatie
Authenticatie is het proces waarbij iemand nagaat of een gebruiker, een andere computer of applicatie daadwerkelijk is wie hij beweert te zijn.
Client
Aanmelden
Server
JWT
// create the webtoken
const token = jwt.sign(
{ userId: user.id, email: user.email },
process.env.TOKEN_SALT,
{ expiresIn: '1h' }
);
// add token to cookie in response
res.cookie('token', token, { httpOnly: true });
// redirect to home page
res.redirect('/');
Validatie, authenticatie en autorisatie
Authenticatie
Autorisatie
import jwt from 'jsonwebtoken';
export const jwtAuth = (req, res, next) => {
const token = req.cookies.token;
try {
const userPayload = jwt.verify(token, process.env.TOKEN_SALT);
const user = await User.query()
.findOne({id: userPayload.userId,})
.withGraphFetched("role");
// set this in client's request
req.user = user;
next();
} catch(e) {
res.clearCookie('token');
return res.redirect('/login');
}
}
app.get('/', jwtAuth, ShopController.index);
jwt.verify()
Validatie, authenticatie en autorisatie
In deze oefening breid je je applicatie uit met een gastenboek voor Georgette in de bloemetjes te zetten.
Trouwe klanten kunnen wel of niet, (naargelang hun rol) een berichtje nalaten