Closed aveein closed 1 year ago
Ah you're right, there is no form or SSR example here.
csrf-sync has a processing as a form example - where csrf-csrf
works similarly. In your template, you render the token as a hidden field on your form, similar to this:
<form action="/transfer.do" method="post">
<input
type="hidden"
name="CSRFToken"
value="OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWEwYzU1YWQwMTVhM2JmNGYxYjJiMGI4MjJjZDE1ZDZMGYwMGEwOA=="
/>
[...]
</form>
And you make sure you have configured the getTokenFromRequest
option when initializing csrf-csrf
, where the key is the name of the form field:
getTokenFromRequest = (req) => {
return req.body['CSRFToken'];
}
Please note that you should make this function explicit. The implicit nature of the default behavior in csurf
for this same functionality is the reason csurf
's default configuration is insecure. If you need to support BOTH form submits and the header option:
getTokenFromRequest = (req) => {
const contentType = req.headers['content-type'];
if (contentType.includes('form')) {
return req.body['CSRFToken'];
} else {
return req.headers['x-csrf-token'];
}
}
If you need to support multipart form data it gets a bit trickier and you'll need to be familiar with your multipart form processor (e.g. multer - or whatever it is you're using).
still getting invalid csrf i have added getTokenFromRequest app.js
const { doubleCsrf } = require("csrf-csrf");
app.use(cookieParser());
const {
invalidCsrfTokenError, // This is just for convenience if you plan on making your own middleware.
generateToken, // Use this in your routes to provide a CSRF hash + token cookie and token.
validateRequest, // Also a convenience if you plan on making your own middleware.
doubleCsrfProtection, // This is the default CSRF protection middleware.
} = doubleCsrf({
getSecret: () => "Secret", // A function that optionally takes the request and returns a secret
cookieOptions: {
secure : false,
},
// A function that returns the token from the request
getTokenFromRequest: (req) => {
const contentType = req.headers['content-type'];
if (contentType.includes('form')) {
return req.body['CSRFToken'];
} else {
return req.headers['x-csrf-token'];
}
},
});
app.use(doubleCsrfProtection);
my form
<form class="login-form" action="/login" method="POST">
<input type="hidden" name="CSRFToken" value="token" >
</form>
my form
<form class="login-form" action="/login" method="POST"> <input type="hidden" name="CSRFToken" value="token" > </form>
I'm assuming this form also contains the username and password field, as well as a submit button? If the form contains all of the fields and a submit button, then when the submit button is clicked, the POST request will be made to the action path, with all of the field values mapped to their names as form data.
For form data, do you have the body parser middleware registered before csrf-csrf?
This isn't really something that is included in the docs (maybe it would be worth a mention), but the csrf-csrf
docs assume you either know, or would otherwise reference express documentation for non csrf-csrf
things
yes it is included before csrf-csrf you can see my code here https://github.com/aveein/node-js-csrf
full form code
<form class="login-form" action="/login" method="POST">
<input type="hidden" name="CSRFToken" value="<%= token %>" >
<div class="form-control">
<label for="email">Email</label>
<input type="text" name="email" id="email">
</div>
<div class="form-control">
<label for="password">Password</label>
<input type="password" name="password" id="password">
</div>
<button class="btn" type="submit">Login</button>
</form>
Hey @aveein sorry for the delay, I took a quick look at the repo and it looks like it should work. I'd pull it down and check myself, but there's a bit of stuff in the repo that shouldn't have been checked in. You shouldn't commit the node_modules folder to your repo - this should be in your git ignore file, among other things.
The recommendation I can make to you at this point is when you request your login page, check the Network tab of the dev tools and take a look at the GET request for the login page. Is there any warnings on the Set-Cookie
header or anything else that may indicate or imply that the cookie isn't working for some reason?
Depending on your specific local setup, you may need to change the sameSite value and/or the name of the cookie to remove the secure prefix just for development env.
Sorry for my unprofessionalism push i was in hurry to show you my bad Yes, it was with the cookie name that was blocking i think many of were having the same problem. Thank you!! I will refactor it and push it again so that others can see :) Updated : https://github.com/aveein/node-js-csrf This package is awesome!!
Glad it's working!
This is mentioned in the README:
Change for development
The security prefix requires the secure flag to be true and requires requests to be received via HTTPS, unless you have your local instance running via HTTPS, you will need to change this value in your development environment.
exports.getLogin = (req,res,next)=>{ const token = req.csrfToken(true);
}