ForbiddenError: invalid csrf token, express js
{{csrfToken}}
isn't an EJS construction, so it's not expanded at all and is probably sent literally to your server.
This should work better:
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
The middleware is setting csrftoken
though, with lowercase 't', where the template expects an uppercase 'T':
res.locals.csrftoken = req.csrfToken(); // change to `res.locals.csrfToken`
You also generate two different tokens, which is probably not what you want. Store the token in a variable and reuse that:
app.use(function (req, res, next) { var token = req.csrfToken(); res.cookie('XSRF-TOKEN', token); res.locals.csrfToken = token; next();});
And lastly, you probably have to move your middleware to before the route declarations, otherwise it won't be called:
app.use(function (req, res, next) { var token = req.csrfToken(); res.cookie('XSRF-TOKEN', token); res.locals.csrfToken = token; next();});app.use('/', routes);app.use('/users', users);app.use('/profile', profile);
My Express version is 6.14.4. The most important matter is you have to maintain the order of the line.App.js
var cookieParser = require('cookie-parser');var csrf = require('csurf');var bodyParser = require('body-parser');//order of bellow lins is very importantapp.use(bodyParser.urlencoded({ extended: false }))app.use(cookieParser())app.use(csrf({ cookie: true }))
routes/index.js
var express = require('express');var router = express.Router();router.get('/user/signup', function(req, res, next){ console.log("csruf: "+req.csrfToken()); res.render('user/signup', { csrfToken: req.csrfToken() });});router.post('/postuser', function(req, res, next){ //res.render('/'); res.redirect('/');});
view file
<form action="/postuser" method="POST"> <div class="form-group"> <label for="email"> E-Mail</label> <input type="text" id="email" name="email" class="form-control"> </div> <div class="form-group"> <label for="password">Password</label> <input type="password" id="password" name="password" class="form-control"> </div> <input type="hidden" name="_csrf" value="{{csrfToken}}"> <button type="submit" class="btn btn-primary">Sign Up</button> </form>