Step 11: Add auth.js
Let's add a new file, auth.js
, to the src/routes
folder.
import express from "express";
import UserDao from "../data/UserDao.js";
import ApiError from "../model/ApiError.js";
import { verifyPassword } from "../password.js";
import { factory } from "../debug.js";
const debug = factory(import.meta.url);
const router = express.Router();
export const userDao = new UserDao();
router.post("/login", async (req, res, next) => {
debug(`${req.method} ${req.path} called...`);
try {
debug(`Parse request body..`);
const { email, password } = req.body;
if (!email || !password) {
throw new ApiError(
400,
"You must provide an email and a password to login."
);
}
debug(`Find the user..`);
const users = await userDao.readAll({ email });
if (users.length === 0) {
throw new ApiError(403, "Wrong email or password!");
}
// Since emails are unique, there will be only one matching user
const user = users[0];
debug("Verify password..");
const result = verifyPassword(password, user.password);
if (!result) {
throw new ApiError(403, "Wrong email or password!");
}
debug("Prepare the payload..");
res.status(201).json({
status: 201,
message: `Successfully signed in!`,
data: {
name: user.name,
email: user.email,
},
});
debug(`Done with ${req.method} ${req.path}`);
} catch (err) {
debug(`There was an error processing ${req.method} ${req.path} `);
next(err);
}
});
export default router;
Notice we have a POST request through the login
route. This choice is more of a convention. You can think of signing in as a process that creates a resource
(such as an authentication token or session).
It also lends itself to provide the username/email and password through the request body.
In response, we send a 201
code to signal success and optionally provide
some user data.
The "HTTP 403 Forbidden" response status code indicates that the server understands the request but refuses to authorize it.
Update src/index.js
We need to import auth
and hook it up to our Express app.
import auth from "./routes/auth.js";
app.use(auth);
Now run the API server and try to make a Postman request for this new route.