Closed YukiThornton closed 6 years ago
Hey, @okunoyuki!
Regarding test state, any cookies held by the session should be available from testSession.cookies
(see e.g. this test). supertest-session
is meant to handle cookie-based sessions transparently; if that's broken, there's a bug.
As far as the problem here, I'm not sure exactly what's up. When you have a moment, could you provide a few more details about the implementation and behavior you're seeing?
res.headers
after calling GET /login
in the test setup, the _csrf
cookie should be present. Is a session cookie (if expected) present as well? And if so, does it (or its backing datastore) contain the expected values?app
look correct, are they also present in testSession.cookies
?Thanks in advance!
Thank you for your quick and kind reply! @rjz
I didn't know about testSession.cookies
but that sounds convenient!
Looks like we use multiple session-related frameworks(express-session and passport). Maybe we shouldn't use both of them at a time?
var passport = require('passport');
app.use(require('express-session')({ secret: 'keyboard cat', resave: false, saveUninitialized: false }));
app.use(passport.session());
For 2, the _csrf cookie exists in res.headers
after calling GET /login
(The following is the output that I got). I assume that I can access 'session cookie' using supertest-session
(I apologize if it's a totally wrong assumption), but I don't know how. Could you show me how to access session?
{ 'cache-control': 'private,no-store,no-cache,must-revalidate,proxy-revalidate',
pragma: 'no-cache',
'set-cookie':
[ '_csrf=XXXXXXXXXXXXXXXXXXXXXXXXXX; Path=/',
'connect.sid=YYYYYYYYYYYYYYYYYYYYYYY; Path=/; HttpOnly' ],
'content-type': 'text/html; charset=utf-8',
'content-length': '1394',
etag: 'W/"572-LEgv480pG9D7SI5tj94/Zg"',
date: 'Mon, 29 Jan 2018 23:36:59 GMT',
connection: 'close' }
For 3, testSession.cookies
had _csrf
cookie with expected values.
Got it—thanks, @okunoyuki!
Depending on what backing store you are using with express-session
, it may not be possible (or desirable) to peek into the session from outside the app. But I think we may be able to make this work from the outside.
First thought: since supertest-session
will echo any cookies it receives, try dropping .send('cookie', ...)
from the test setup:
testSession.get('/login')
.end(function(err, res) {
if (err) {
return done(err);
}
testSession.post('/login')
.type('form')
.send({
username: 'xxxxxxxx',
password: 'xxxxxxxx',
})
.end(done);
});
It looks like the session cookie is being attached correctly (you can see it in the HTTP requests, and it should appear in testSession.cookies['connect.sid']
after the initial request). The next thought, then, would be to make sure the session is being restored correctly inside the app. If you log out req.cookies
in the post
routes, the connect.sid
cookie should match the cookie seen inside the tests. If it doesn't, it's possible that something is missing in the express-session
configuration.
Thank you! @rjz I'm sorry I was pretty busy this week and haven't tried you ideas yet. I'll try them and get back to you next week!
@rjz
Thank you for your advice!
It worked without .send('cookie', ...)
. And I found out that there is something wrong with express-session
configuration since the connect.sid
cookie in the post
routes didn't match the one inside the tests.
Since my problem doesn't seem relevant to supertest-session
for now, you can close this issue. Thank you so much!
Awesome, @okunoyuki, I'm glad to hear that it's working!
Please do be in touch if you run into any other issues.
having the same issue
getting XSRF-TOKEN successfully but when i try to login it shows XSRF-TOKEN mismatch also it is working preety fine on browsers and postman
`const app = require('../../../app.js'); const expect = require('chai').expect; const request = require('supertest'); var csrfToken;
describe('GET /api/csrf-token', () => { it('OK, Getting CSRF Token', (done) => { request(app).get('/api/csrf-token') .expect(200) .then((res) => { const body = res.body; csrfToken=body.csrfToken; expect(body).to.contain.property('csrfToken'); done(); }) .catch((err) => done(err)); }); });
describe('POST /api/users/login', () => { it('OK, Logging in with super admin crediantials', (done) => { request(app).post('/api/users/login') .set('Content-Type', 'application/json') .set("Accept","/") .set("XSRF-TOKEN",csrfToken) .set("Cookie","XSRF-TOKEN",csrfToken) .set("withCredentials",true) .expect(200) .send({"email":"super@abc.com","password":"abc"}) .expect((res) => { const body = res.body; console.log(body); expect(body.message).to.contain.property('Auth Successful'); expect(body).to.contain.property('token'); done(); }) .catch((err) => done(err)); }); }); `
Hi. My team is struggling to implement csrf tokens to our express APIs and run tests correctly. Our app works well on real browsers, but the tests related with sessions fail. We added csrf secret to session in GET request, but we cannot retrieve the secret in subsequent POST request. We're trying to figure out whether we're using supertest-session in a wrong way, or something unexpected is happening (ex. some other Express middlewares interfere the test code). We also want to know how to access session objects in test code to debug more closely. We'd appreciate any help!
Problem
req.session._csrf
inrouter.post('/login')
isundefined
_csrf
key is added toreq.session
inrouter.get('/login')
.Test code
Source code
router.post('/login', function(req, res, next) { var secret = req.session._csrf; var token = req.cookies._csrf; console.log(secret); // undefined console.log(token);
if (tokens.verify(secret, token) === false) { return next(new Error("Invalid Token")); }
// authenticate user });