Development Tip

Passport로 Supertest 요청을 인증하는 방법은 무엇입니까?

yourdevel 2020. 12. 10. 21:23
반응형

Passport로 Supertest 요청을 인증하는 방법은 무엇입니까?


Mocha 및 Supertest로 인증 (로컬 전략) 및 테스트를 위해 Passport.js를 사용하고 있습니다.

Supertest로 세션을 생성하고 인증 된 요청을하려면 어떻게해야합니까?


이를 위해 수퍼 에이전트사용해야 합니다. 하위 모듈이며 supertest. 에이전트 지속 섹션을 살펴보십시오 .

var request = require('superagent');
var user1 = request.agent();
user1
  .post('http://localhost:4000/signin')
  .send({ user: 'hunter@hunterloftis.com', password: 'password' })
  .end(function(err, res) {
    // user1 will manage its own cookies
    // res.redirects contains an Array of redirects
  });

이제 user1인증 된 요청을 만드는 데 사용할 수 있습니다 .


zeMirco가 지적했듯이 기본 superagent모듈은 세션을 지원 하여 자동으로 쿠키를 유지합니다. 그러나 문서화되지 않은 기능을 통해 superagent.agent()기능 을 사용할 수 supertest있습니다.

require('supertest').agent('url')대신 사용하십시오 require('supertest')('url').

var request = require('supertest');
var server = request.agent('http://localhost:3000');

describe('GET /api/getDir', function(){
    it('login', loginUser());
    it('uri that requires user to be logged in', function(done){
    server
        .get('/api/getDir')                       
        .expect(200)
        .end(function(err, res){
            if (err) return done(err);
            console.log(res.body);
            done()
        });
    });
});


function loginUser() {
    return function(done) {
        server
            .post('/login')
            .send({ username: 'admin', password: 'admin' })
            .expect(302)
            .expect('Location', '/')
            .end(onResponse);

        function onResponse(err, res) {
           if (err) return done(err);
           return done();
        }
    };
};

이 시도,

  var request=require('supertest');
  var cookie;
  request(app)
  .post('/login')
  .send({ email: "user@gluck.com", password:'password' })
  .end(function(err,res){
    res.should.have.status(200);
    cookie = res.headers['set-cookie'];
    done();        
  });

  //
  // and use the cookie on the next request
  request(app)
  .get('/v1/your/path')
  .set('cookie', cookie)
  .end(function(err,res){  
    res.should.have.status(200);
    done();        
  });

Andy의 답변에 대한 부록으로 Supertest가 서버를 시작하도록하려면 다음과 같이 할 수 있습니다.

var request = require('supertest');

/**
 * `../server` should point to your main server bootstrap file,
 * which has your express app exported. For example:
 * 
 * var app = express();
 * module.exports = app;
 */
var server = require('../server');

// Using request.agent() is the key
var agent = request.agent(server);

describe('Sessions', function() {

  it('Should create a session', function(done) {
    agent.post('/api/session')
    .send({ username: 'user', password: 'pass' })
    .end(function(err, res) {
      expect(req.status).to.equal(201);
      done();
    });
  });

  it('Should return the current session', function(done) {
    agent.get('/api/session').end(function(err, res) {
      expect(req.status).to.equal(200);
      done();
    });
  });
});

죄송합니다. 제안 된 솔루션 중 어느 것도 저에게 적합하지 않습니다.

함께 supertest.agent()내가 사용할 수 없습니다 app인스턴스를, 나는 서버를 실행 사전과를 지정할 필요가있어 http://127.0.0.1:port, 내가 사용할 수 없으며 또한 나는의 supertest 기대 (주장)를 사용할 수 없습니다 supertest-as-promised에 LIB 등을 ...

cookies사건은 전혀 효과가 없을 것입니다.

그래서 내 해결책은 다음과 같습니다.

당신이 사용하는 경우 Passport.js를 ,이 메커니즘 "토큰 무기명의"를 이용하고 당신은 당신의 사양에 다음 예제를 사용할 수 있습니다 :

var request = require('supertest');
var should = require('should');

var app = require('../server/app.js'); // your server.js file

describe('Some auth-required API', function () {
  var token;

  before(function (done) {
    request(app)
      .post('/auth/local')
      .send({
        email: 'test@example.com',
        password: 'the secret'
      })
      .end(function (err, res) {
        if (err) {
          return done(err);
        }

        res.body.should.to.have.property('token');
        token = res.body.token;

        done();
      });
  });

  it('should respond with status code 200 and so on...', function (done) {
    request(app)
      .get('/api/v2/blah-blah')
      .set('authorization', 'Bearer ' + token) // 1) using the authorization header
      .expect(200)
      .expect('Content-Type', /json/)
      .end(function (err, res) {
        if (err) {
          return done(err);
        }

        // some `res.body` assertions...

        done();
      });
  });

  it('should respond with status code 200 and so on...', function (done) {
    request(app)
      .get('/api/v2/blah-blah')
      .query({access_token: token}) // 2) using the query string
      .expect(200)
      .expect('Content-Type', /json/)
      .end(function (err, res) {
        if (err) {
          return done(err);
        }

        // some `res.body` assertions...

        done();
      });
  });
});

사용자를 인증하는 도우미 기능을 원할 수 있습니다.

test/auth-helper.js

'use strict';

var request = require('supertest');
var app = require('app.js');

/**
 * Authenticate a test user.
 *
 * @param {User} user
 * @param {function(err:Error, token:String)} callback
 */
exports.authenticate = function (user, callback) {
  request(app)
    .post('/auth/local')
    .send({
      email: user.email,
      password: user.password
    })
    .end(function (err, res) {
      if (err) {
        return callback(err);
      }

      callback(null, res.body.token);
    });
};

생산적인 하루 보내세요!


나는 당신이 CookieSession 미들웨어를 사용하고 있다고 가정 할 것입니다.

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:

var Cookie          = require("express/node_modules/connect/lib/middleware/session/cookie")
  , cookieSignature = require("express/node_modules/cookie-signature")

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:

var cookie = new Cookie()
  , session = {
      passport: {
        user: Test.user.id
      }
    }

var val = "j:" + JSON.stringify(session)
val = 's:' + cookieSignature.sign(val, App.config.cookieSecret)
Test.cookie = cookie.serialize("session",val)

Test.user.id was previously defined in the portion of my beforeEach chain that defined the user I was going to "login". The structure of session 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 into Test.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:

it("should logout a user", function(done) {
  r = request(App.app)
    .del(App.Test.versionedPath("/logout"))
    .set("cookie", Test.cookie)
    // ... other sets and expectations and your .end
}

Notice the call to set with "cookie" and Test.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.

참고URL : https://stackoverflow.com/questions/14001183/how-to-authenticate-supertest-requests-with-passport

반응형