Step 10

Adding auth route handler

Let's add another route for our auth handlers

src/routes/auth.js

const express = require('express');
const jwt = require('jsonwebtoken');
const { SECRET, EXPIRES_IN } = require('../config');
const User = require('../models/user');
const router = express.Router();

router.post('/signup', async (req, res) => {
	const { username, password } = req.body;
	if (!username) return res.status(400).send('Please provide a username');
	if (!password) return res.status(400).send('Please provide a password');

	let user = await User.findOne({ where: { username } });
	if (user) return res.status(401).send(`User with the username: ${username} already exists`);

	user = await User.create({ username, password });
	const token = jwt.sign({ id: user.id }, SECRET, { expiresIn: EXPIRES_IN });
	res.send({
		user,
		token
	});
});

router.post('/login', async (req, res) => {
	const { username, password } = req.body;
	if (!username) return res.status(400).send('Please provide a username');
	if (!password) return res.status(400).send('Please provide a password');

	let user = await User.scope('withPassword').findOne({ where: { username } });
	if (!user) return res.status(400).send(`User with the username: ${username} does not exist`);

	if (!user.comparePassword(password)) return res.status(401).send(`Incorrect password`);

	const token = jwt.sign({ id: user.id }, SECRET, { expiresIn: EXPIRES_IN });
	res.send({
		user,
		token
	});
});

module.exports = router;

For the "/signup" route, we return an error if we find a user in our database with the same username, and if not, we create the user in our database and create a new JWT where the data in the token is {id: user.id}. Finally, we send the user object and token string to the user.

For the "/login" route, we do essentially the same thing as signup, except we compare the passwords and we aren't creating a new user. Remember, we must use the "withPassword" scope because by default, we do not expose the password to the user. When we send the response to the user, Express will internally call the "toJSON()" method on our user object and based on the custom logic we made in the User model, we delete the password.

Now we register our auth router with our HTTP Server

src/index.js

const express = require('express');
const passport = require('passport');
const { PORT } = require('./config');
const { extractUser, passportMiddleware } = require('./middleware/passport');
const books = require('./routes/books');
const auth = require('./routes/auth');

const app = express();

app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(passportMiddleware(passport).initialize());
app.use(extractUser());

app.use('/api/books', books);
app.use('/api/auth', auth);

app.listen(PORT, () => {
	console.log(`Listening on port: ${PORT}`);
});

Last updated

Was this helpful?