How do you you set up a working server to test CSURF in Postman, as per the CSURF documentation:
http://expressjs.com/en/resources/middleware/csurf.html
Thanks for your question and answer, it helped solve part of the puzzle setting up Postman. I'm posting my own answer for a bit of clarity on a couple of points, with the bonus of automating copying the token into Postman requests
1. Cookie parser comes first
app.use(cookieParser())
2. Send _csrf cookie
app.use(csrf({ cookie: { httpOnly: true, }}))
This returns Cookie 1: _csrf.
Using httpOnly is recommended because it keeps the cookie out of the reach of JavaScript and is more secure
3. Send XSRF-Token cookie
Sets a second cookie that needs to be returned with each request
app.use((req, res, next) => {
res.cookie('XSRF-TOKEN', req.csrfToken())
next()
})
4. Return XRSF-Token* header
This needs to be on every request (all that use POST, DELETE, etc) and is different after every call
There are alternatives to using a header (a body property or query can be used instead) but using a header seems cleaner, especially when using JSON
a. Set up and send a GET request on Postman (Since get requests don't check for csrf by default)
b. Set up a POST request in Postman, set this header, using the cookie value from the GET request
XSRF-Token abc123...
*Note the hyphen (-), not underscore (_)
4. Automatically set header in Postman
Postman automatically keeps and sends cookies, like a browser, but we need some way to obtain the token from the last request and copy it into our next request
Tests in Postman run a snippet of Javascript after each request and will work well for this purpose
I set this test up on one of my GET requests, so I'm sure it won't be invalid on the first request
// A Postman Test script
const xsrf_token = postman.getResponseCookie('XSRF-Token')
postman.setEnvironmentVariable('xsrf_token', xsrf_token.value)
Then, in your POST request's headers, switch out the copy pasted string for the environment variable
XSRF-Token {{xsrf_token}}
Now you should be right to POST to your heart's content in Postman
I've had to relearn this a couple of times so I thought it'd be handy for everyone to see the breakdown:
In your server:
In index.js:
const app = require('./app')
app.set('port', 5000);
app.listen(app.get('port'), () => {
console.log('App running on port', app.get('port'));
});
In app.js:
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })
// create express app
var app = express()
// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())
app.get('/form', csrfProtection, function (req, res) {
// pass the csrfToken to the view
// res.render('send', { csrfToken: req.csrfToken() })
res.send({csrfToken: req.csrfToken() })
})
app.post('/process', parseForm, csrfProtection, function (req, res) {
res.send('data is being processed')
})
module.exports = app;
Start your server
In Postman:
GET Request:
Send a GET request to http://localhost:5000/form
Hit 'Send'. Below the request info you should see the following in the response data:
Copy the string between the quotation marks. (In this example: H3DsAwqv-FuM06caBMOh6QZRFaILYgFyqFlA )
POST Request:
Set up a POST request to http://localhost:5000/process
Click the 'Body' tab and select the radio button for 'x-www-form-urlencoded'.
Enter a new key "_csurf" and paste the string value we received in the GET request.
Your POST request should now look like this set up:
Hit 'Send'. You should now see this information:
If you see 'data is being processed' then you know it's working!
I made a YouTube tutorial in case this makes things easier:
https://youtu.be/QruvuwM-kkU
Related
So I'm new to Backend and is learning about HTTP request. As far as I know GET is for getting a resource from backend and displays it on the browser. Then there is POST to post a resource, but where does it posted? I'm using express as framework. This is my code:
let bodyParser = require('body-parser');
let express = require('express');
let app = express();
app.use(bodyParser.urlencoded({extended: false}));
app.post('/name', (req, res) => {
let first = req.body.first;
let last = req.body.last;
res.json({
'name': `${first} ${last}`
})
})
module.exports = app;
I successfully displayed the respond (a JSON with properties name: ${first} ${last}) after I submitted the form. But where does this JSON is saved? How can I access the JSON again?
Do I still need to push it to database to have access to submitted JSON? Because I thought before, POST will POST the submitted value.
Any helpful answer would be appreciated.
res.json is similar to sending response data back to the client side. At the client side, you can use a variable to store the result of calling this http request and then you can use the data it sends back.
I can't get any POST requests with the express framework.
This is my code
var express = require("express");
var app = express();
app.set("view engine","ejs")
app.get("/", function(req, res){
res.render("home");
});
app.post("/addfriend", function(req, res){
res.send("you have reached the post route succesfully");
});
app.get("/friends", function(req, res){
var friends =["lara","tommy","miranda","faith","locas"];
res.render("friends",{friends : friends});
});
app.listen(3000, function(){
console.log("server is listening on port 3000");
});
any suggestion please.
Few observations.
1)You are missing body parser for your app.js ( if in future you want to read form data).
just add this to your app,js
const app = express();
app.use(bodyParser.json());
Wherever you are using trying to send post request for example a HTML form or a button does it have correct route, it should match with this post route /addfriend.
Browser always send get request to server from browser, to specifically send post request use postman, curl or a HTML form.
If you are using postman try this https://learning.postman.com/docs/sending-requests/requests/#sending-body-data
For the difference between get and post follow this
Edit :-
Http post request means :- "The HTTP POST method sends data to the server. The type of the body of the request is indicated by the Content-Type header."
get request :- "The HTTP GET method requests a representation of the specified resource. Requests using GET should only be used to request data (they shouldn't include data)."
I'm trying to get the value of a cookie with a cookie-parser.
The code is as follows (app.js):
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
app.use(cookieParser());
app.get('/', function (req, res) {
console.log('Cookies: ', req.cookies);
});
The log shows the cookies and their value but the page shows the error ERR_EMPTY_RESPONSE
If I do not use this, the web loads perfectly.
I hope you can help me, thanks in advance.
Every middleware function must either invoke the next one in the chain to continue request processing, or finish the response by itself (using res.end() or res.send(...) or similar functions). In your case you're not passing control to next middleware, so response is ending with your function - but you're not properly ending the response either. That's why the error.
If you just want to print cookie value, you can invoke the next middleware in chain by using :
app.get('/', function (req, res, next) {
console.log('Cookies: ', req.cookies);
next(); //--> Added to call next middleware in chain
});
Do you have this at the bottom?
app.listen(8080)
i just want to try basic methods to set cookie and show in request head.
front-end is just a basic html form with username and password text input, use POST method to transfer data.
below is code based on express.
server just receive req.body, then set it as cookie with domain: localhost:1338/base
cookieRouter.js:
var express = require('express');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var router = express.Router();
router.use(bodyParser.urlencoded({ extended: false }));
router.use(cookieParser());
router.get('/', function (req, res) {
res.send('this is a router base page!');
});
router.get('/index1.html', function (req, res) {
res.sendFile(__dirname + '/index1.html');
});
router.post('/index1.html', function (req, res) {
res.cookie('name', req.body, { domain: 'localhost:1338', path: '/base' });
res.send(req.body);
});
module.exports = router;
app.js
var express = require('express');
var app = express();
var cookieRouter = require('./cookieRouter.js');
app.get('/', function (req, res) {
res.send('this is home page!');
});
app.use('/base', cookieRouter);
app.listen(1338);
after run app.js, request header has set-cookie value obviously. but can't get it into request header, and req.cookies is empty object {}, even after refreshing the web.
but if i just use simplest demo, it can work, for instance:
router.get('/', function (req, res) {
res.cookie('name', 'test');
});
one more thing, i feel the trouble with express is that only one res.send(), res.redirect()... can be sent as by default it will add head automatically, otherwise, it will come up with error: Can't set headers after they are sent.
someone said add return can solve this problem, but i failed, so want to how how to add, can anyone give an complete demo?
The cookie is missing because the domain attribute is incorrect -- 'localhost:1338' need to be changed to 'localhost'. Port information should not be included in domain.
Yes, according to the Network panel of browser dev tool, there is a Set-Cookie response header (as the screenshot displayed). However, if you check Application - Cookies panel in Chrome (or corresponding panel in other browsers), you will find that: the cookie specified by Set-Cookie header is not there. Browser does not store it and won't send it in the following HTTP requests.
Also, please note that as the cookie's path is /base, only the HTTP requests whose URL starts with /base can send the cookie.
I'm using cookie-parser, all the tutorial talk about how to set cookie and the time it expiries but no where teach us how to get the value of these cookie
For people that stumble across this question, this is how I did it:
You need to install the express cookie-parser middleware as it's no longer packaged with express.
npm install --save cookie-parser
Then set it up as such:
const cookieParser = require("cookie-parser");
const app = express();
app.use(cookieParser());
Then you can access the cookies from
req.cookies
Hope that help.
First note that Cookies are sent to client with a server request and STORED ON THE CLIENT SIDE. Every time the user loads the website back, this cookie is sent with the request.
So you can access the cookie in client side (Eg. in your client side Java script) by using
document.cookie
you can test this in the client side by opening the console of the browser (F12) and type
console.log(document.cookie);
you can access the cookie from the server (in your case, expressjs) side by using
req.cookies
Best practice is to check in the client side whether it stored correctly. Keep in mind that not all the browsers are allowing to store cookies without user permission.
As per your comment, your code should be something like
var express = require('express');
var app = express();
var username ='username';
app.get('/', function(req, res){
res.cookie('user', username, {maxAge: 10800}).send('cookie set');
});
app.listen(3000);
hope this will help you
const app = require('express')();
app.use('/', (req, res) => {
var cookie = getcookie(req);
console.log(cookie);
});
function getcookie(req) {
var cookie = req.headers.cookie;
// user=someone; session=QyhYzXhkTZawIb5qSl3KKyPVN (this is my cookie i get)
return cookie.split('; ');
}
output
['user=someone', 'session=QyhYzXhkTZawIb5qSl3KKyPVN']
Just want to add that we shouldn't be using modules to do trivial stuff. Modules are very convenient and fast forward development, but keep us from learning by creating infrastructural code.
I'm a professor not a boss so I value more programmers knowledge/skill development than to write code in lesser time without learning anything...
Back to business...
Unless you need signed cookies, or anything more complex, it's perfectly possible to write your own middleware to parse cookies and add the values to the rest of the pipeline as the module does.
app.use((req, res, next) => {
const { headers: { cookie } } = req;
if (cookie) {
const values = cookie.split(';').reduce((res, item) => {
const data = item.trim().split('=');
return { ...res, [data[0]]: data[1] };
}, {});
res.locals.cookie = values;
}
else res.locals.cookie = {};
next();
});
Anywhere you need to read the cookie it's available via res.locals.cookie, conveniently formatted as an object.
You could even add a custom cryptography strategy here to make sure no one is reading your cookie.
Just remember middlewares are ordered, so this one has to be added before any other middleware or route that uses the cookie.