Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to authenticate Supertest requests with Passport /Facebook strategy/?

I'm using Passport.js for authentication (Facebook strategy) and testing with Mocha and Supertest. How can I create a session and make authenticated requests with Supertest for Facebook strategy?

Here is the example test for when user not logged in:

  describe 'when user not logged in', ->

    describe 'POST /api/posts', ->
      it 'respond with 401', (done)->
        request(app).
          post(API.url('posts')).
          set('Accept', 'application/json').
          send(post: data).
          expect('Content-Type', /json/).
          expect(401, done)

Thank you for advice :D

like image 418
Zeck Avatar asked Dec 17 '13 17:12

Zeck


People also ask

What is Passport authentication?

Passport is a popular, modular authentication middleware for Node. js applications. With it, authentication can be easily integrated into any Node- and Express-based app. The Passport library provides more than 500 authentication mechanisms, including OAuth, JWT, and simple username and password based authentication.

Can passport use multiple strategies?

Passport's middleware is built in a way that allows you to use multiple strategies in one passport.


2 Answers

There are few different things here it looks like, so I've divided my answer into two parts.

1) You first must create test users through the Facebook. You can do so via one of two methods, 1) Facebook's Graph API, or 2) Through the Roles page of your application.

2) The recommend method for persisting sessions with SuperTest is using a SuperAgent method called .agent() to persist sessions. Anything you can do with SuperAgent, you can do with SuperTest. See this Github post for more.

var supertest = require('supertest');
var app = require('../lib/your_app_location');

describe('when user not logged in', function() {
    describe('POST /api/posts', function() {
        var agent1 = supertest.agent(app);

        agent1
            .post(API.url('posts'))
            .set('Accept', 'application/json')
            .send(post: data)
            .(end(function(err, res) {
                should.not.exist(err);
                res.should.have.status(401);
                should.exist(res.headers['set-cookie']);
                done();
            }));
    });
});

There are some other good code snippets on the VisionMedia Github. Please find them here.

like image 91
erichrusch Avatar answered Sep 30 '22 09:09

erichrusch


The general solution is to create a cookie jar that will be re-used between requests.

The following example isn't passport specific, but should work:

var request = require('request');

describe('POST /api/posts', function () {
    // Create a new cookie jar
    var j = request.jar();
    var requestWithCookie = request.defaults({jar: j}),

    // Authenticate, thus setting the cookie in the cookie jar
    before(function(done) {
        requestWithCookie.post('http://localhost/user', {user: 'foo', password: 'bar'}, done);
    });

    it('should get the user profile', function (done) {
        requestWithCookie.get('http://localhost/user', function (err, res, user) {
            assert.equal(user.login, 'foo');
            done();
        });
    });
});
like image 34
Paul Mougel Avatar answered Sep 30 '22 08:09

Paul Mougel