I’ve been trying to implement CSRF into my code for a dummy social media application. I have been trying to use double CSRF (CSRF-CSRF) but I just can not get it to work. Every time I get past my Sign In page i get the dreaded “ForbiddenError: invalid csrf token at doubleCsrf”.
Below is my App.js:
const path = require('path');
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);
const { doubleCsrf: csrf } = require('csrf-csrf');
const cookieParser = require('cookie-parser');
const User = require('./models/users');
const MONGODB_URI = "mongodb+srv://#######@cluster0.ecbbaof.mongodb.net/Personal?retryWrites=true&w=majority&appName=Cluster0"
const app = express();
const store = new MongoDBStore({
uri: MONGODB_URI,
collection: 'sessions',
});
const csrfProtection = csrf({
getSecret: () => 'supersecret',
getTokenFromRequest: (req) => req.body._csrf,
});
app.set('view engine', 'ejs');
app.set('views', 'views');
const mainRoutes = require("./routes/main")
const authRoutes = require("./routes/auth");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(
session({
secret: 'my secret',
resave: false,
saveUninitialized: false,
store: store,
})
);
/** CSRF-CSRF PACKAGE */
app.use(cookieParser('supersecret'));
app.use(csrfProtection.doubleCsrfProtection);
app.use((req, res, next) => {
if (!req.session.user) {
return next();
}
User.findById(req.session.user._id)
.then((user) => {
req.user = user;
next();
})
.catch((err) => console.log(err));
});
app.use((req, res, next) => {
res.locals.isAuthenticated = req.session.isLoggedIn;
res.locals.csrfToken = req.csrfToken();
next();
});
app.use(mainRoutes);
app.use(authRoutes);
mongoose
.connect(MONGODB_URI)
.then((result) => {
app.listen(3001);
console.log("connected")
})
.catch((err) => {
console.log(err);
});
Here is also my HTML template. I am using EJS:
<form action="/signup" method="POST">
<div class="form-control">
<label for="email">E-mail</label>
<input type="email" name="email" id="email">
</div>
<div class="form-control">
<label for="username">Username</label>
<input type="text" name="username" id="Username">
</div>
<div class="form-control">
<label for="password">Password</label>
<input type="password" name="password" id="password">
</div>
<input type="hidden" name="_csrf" value="<%= csrfToken %>" />
<button class="btn" type="submit">Sign up</button>
</form>
I’ve tried everything things like clearing browser cache, & configuring CSRF settings and still nothing. I’m pretty new to things like this so please excuse me on that.
error always seems to be at the “const csrfProtection = csrf” section
If anyone know anything I’m doing wrong please point it out 🙂