I'm using Passport.js for authentication (local strategy) and testing with Mocha and Supertest.
How can I create a session and make authenticated requests with Supertest?
I'm using Passport.js for authentication (local strategy) and testing with Mocha and Supertest.
How can I create a session and make authenticated requests with Supertest?
I'm going to assume that you're using the CookieSession middleware.
As grub mentioned, your goal is to get a cookie value to pass to your request. However, for whatever reason (at least in my testing), supertest won't fire 2 requests in the same test. So, we have to reverse engineer how to get the right cookie value. First, you'll need to require the modules for constructing your cookie:
Yes, that's ugly. I put those at the top of my test file.
Next, we need to construct the cookie value. I put this into a
beforeEach
for the tests that would require an authenticated user:Test.user.id
was previously defined in the portion of mybeforeEach
chain that defined the user I was going to "login". The structure ofsession
is how Passport (at least currently) inserts the current user information into your session.The
var val
lines with"j:"
and"s:"
are ripped out of the Connect CookieSession middleware that Passport will fallback on if you're using cookie-based sessions. Lastly, we serialize the cookie. I put"session"
in there, because that's how I configured my cookie session middleware. Also,App.config.cookieSecret
is defined elsewhere, and it must be the secret that you pass to your Express/Connect CookieSession middleware. I stash it intoTest.cookie
so that I can access it later.Now, in the actual test, you need to use that cookie. For example, I have the following test:
Notice the call to
set
with"cookie"
andTest.cookie
. That will cause the request to use the cookie we constructed.And now you've faked your app into thinking that user is logged in, and you don't have to keep an actual server running.
You should use superagent for that. It is lower level module and used by
supertest
. Take a look at the section Persisting an agent:Now you can use
user1
to make authenticated requests.As an addendum to Andy's answer, in order to have Supertest startup your server for you, you can do it like this:
I'm sorry, but neither of suggested solutions doesn't work for me.
With
supertest.agent()
I can't use theapp
instance, I'm required to run the server beforehand and specify thehttp://127.0.0.1:port
and moreover I can't use supertest's expectations (assertions), I can't use thesupertest-as-promised
lib and so on...The
cookies
case won't work for me at all.So, my solution is:
If you are using Passport.js, it utilizes the "Bearer token" mechanism and you can use the following examples in your specs:
You may want to have a helper function to authenticate users:
test/auth-helper.js
Have a productive day!
As zeMirco points out, the underlying
superagent
module supports sessions, automatically maintaining cookies for you. However, it is possible to use thesuperagent.agent()
functionality fromsupertest
, through an undocumented feature.Simply use
require('supertest').agent('url')
instead ofrequire('supertest')('url')
:Try this,