Indice
Gestire autenticazioni di utenti con Bun e framework Express.js
Autore: Fabio Di Matteo
Ultima revisione: 08/07/2026 14:53
Sto usando il framework express.js , ma i principi sono applicabili con ogni framework web.
Base utenti
In questo caso uso come base per gli utenti un file toml. Con un array chiamato users. Ecco un esempio.
users.toml
# `mkpasswd -m bcrypt` for gen password. [[users]] username = "fabio" password = "<hash password bcrypt>" [[users]] username = "rita" password = "<hash password bcrypt>"
La password si puo' ottenere col comando `mkpasswd -m bcrypt` .
Logica
Per ogni rotta che si deve proteggere con autenticazione controllo se esiste una variabile di sessione logged=“yes”. Se non trovo la variabile di sessione allora avviene un redirect alla rotta che porta al form di autenticazione.
A sua volta il form ha un'action su /dologin che controlla se esiste un utente che ha la password e il relativo nome utente specificati nei campi del form. Se esiste l'utente allora assegno a logged il valore yes.
Le rotte
import express from "express"; import * as utils from "./utils.js" ; const app = express(); const session = require('express-session'); app.use(session({ secret: 'secret_dfhgighd', // required – signs the session ID cookie resave: false, // don’t save unchanged sessions saveUninitialized: true, // save new but unmodified sessions cookie: { // cookie options for the session ID maxAge: 60000*60*24*10, // 60.000 = 1 minute (ms) httpOnly: true, secure: false, // set true for HTTPS (or 'auto') sameSite: 'lax' // or 'strict', 'none', 'auto' } })); const mount_point="/myapp"; app.get("/login", (req,res) =>{ res.render("login", {mount_point: mount_point}); }); app.post("/dologin", async (req,res) =>{ const user= req.body.username; const pass= req.body.password; const ok = await utils.is_valid_user(user, pass); if (ok){ req.session.logged="yes"; } res.redirect(mount_point); }); app.get("/logout", (req,res) =>{ req.session.logged="no"; res.redirect(mount_point); });
Funzioni nel file utils.js
utils.js
import bcrypt from 'bcrypt'; import path from "path"; import { fileURLToPath } from "url"; import { dirname } from "path"; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); import { readFileSync } from "node:fs"; import toml from "toml"; const toml_users=`${__dirname}/users.toml` export function only_logged(req,res){ if (req.session.logged!="yes"){ return false; }else{ return true; } } export async function is_valid_user(u,p){ const data = readFileSync(toml_users, "utf8"); const conf = toml.parse(data); for (const e of conf.users){ // console.log(e.username+" -- "+e.password); if (e.username==u){ const match_pass = await bcrypt.compare(p, e.password); if (match_pass){ console.log("Utente corretto."); return true; } } } return false; }
Template per il form di login
views/login.ejs
<%- include('header') %> <div class="container card w-25 mt-5 p-3"><h1 class="mb-3">Login please...</h1> <form method="post" action="<%= mount_point %>/dologin"> <div class="mb-3"> <label for="username" class="form-label">Username</label> <input type="username" class="form-control" name="username" aria-describedby="usernameHelp"> <div id="usernameHelp" class="form-text">Your username, can be a email</div> </div> <div class="mb-3"> <label for="password" class="form-label">Password</label> <input type="password" class="form-control" name="password"> </div> <button type="submit" class="btn btn-secondary">Login</button> </form> </div> <%- include('footer') %>
Generare password bcrypt
Ecco una rotta che genera password bcrypt in questo modo:
GET /genpassword/mypassword
dove my password è la password che verra trasformata in hash bcrypt.
... import bcrypt from "bcrypt"; app.get("/genpassword/:password", async (req, res) => { const saltRounds = 10; const password = req.params.password; const hash = await bcrypt.hash(password, saltRounds); res.send(hash); }); ...
