2016-02-15 3 views
4

Я создаю универсальное приложение React и используя this project в качестве базы. Я успешно прокси-запросы (используя http-proxy) на моем сервере Laravel. Однако я новичок в Nodejs, и я не знаю, как лучший метод безопасного хранения JWT с прокси-сервера для клиента.Хранение токена из API w/Express http-proxy

Моя первоначальная мысль заключалась в том, чтобы хранить токен в localStorage, но проблема в том, что у экспресс-сервера не будет доступа к нему. Таким образом, моя следующая догадка заключается в том, чтобы хранить его как файл cookie, но я не уверен, как его хранить на клиенте или включать в него как заголовок для всех исходящих запросов (кроме того, мне, скорее всего, понадобится какое-то промежуточное ПО csrf).

Как я могу манипулировать ответом от моего сервера api, чтобы поставить токен в cookie, который установлен на клиенте, а затем использовать его как токен-носитель для всех запросов api?

// server.js 
const targetUrl = 'http://' + config.apiHost + ':' + config.apiPort; 
const app = new Express(); 
const server = new http.Server(app); 

const proxy = httpProxy.createProxyServer({ 
    target: targetUrl, 
    changeOrigin: true 
}); 

// Proxy to Auth endpoint 
app.use('/auth', (req, res) => { 
    // on a successful login, i want to store the token as a cookie 
    proxy.web(req, res, {target: targetUrl}); 
}); 

// Proxy to api endpoint 
app.use('/api', (req, res) => { 
    // use the token in the cookie, and add it as a authorization header in the response 
    proxy.web(req, res, {target: targetUrl}); 
}); 

ответ

1

Учитывая, что ответ от Идент конечной точки в Laravel, как это:

{ 
    "token" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" 
} 

Этот код будет делать то, что вы хотите:

// server.js 
const targetUrl = 'http://' + config.apiHost + ':' + config.apiPort; 
const Express = require('express'); 
const http = require('http'); 
const httpProxy = require('http-proxy'); 
const app = new Express(); 
const server = new http.Server(app); 
const Cookies = require("cookies") 

const proxy = httpProxy.createProxyServer({ 
    target: targetUrl, 
    changeOrigin: true 
}); 

// Proxy to Auth endpoint 
app.use('/auth', (req, res) => { 
    // on a successful login, i want to store the token as a cookie 
    // this is done in the proxyRes 
    proxy.web(req, res, {target: targetUrl}); 
}); 

// Proxy to api endpoint 
app.use('/api', (req, res) => { 
    // use the token in the cookie, and add it as a authorization header in the response 
    var cookies = new Cookies(req, res) 
    req.headers.authorization = "JWT " + cookies.get('jwt-token'); 
    proxy.web(req, res, {target: targetUrl}); 
}); 

proxy.on('proxyRes', function(proxyRes, req, res) { 
    if (req.originalUrl === '/auth') { 
     var cookies = new Cookies(req, res) 
     var body = ''; 
     var _write = res.write; 
     var _end = res.end; 
     var _writeHead = res.writeHead; 
     var sendHeader = false; 

     res.writeHead = function() { 
      if (sendHeader) { 
       _writeHead.apply(this, arguments); 
      } 
     } 
     res.write = function (data) { 
      body += data; 
     } 
     res.end = function() { 
      sendHeader = true; 
      var parsed = JSON.parse(body); 
      cookies.set('jwt-token', parsed.token); 
      _write.apply(this, [ body ]); 
      _end.apply(this, arguments); 
     } 

    } 
}); 
+0

Похоже, единственный вопрос, я нахожусь работающий в том, что var parsed = JSON.parse (тело); выкинуть ошибку: Неожиданный токен. Ответ от сервера - json. Я также попытался использовать JSON.parse (body.toString ('utf8')), но я все равно получаю ту же ошибку – csm232s

+0

Пожалуйста, напишите, что такое 'body'. 'console.log (body);' Вероятно, некоторые дополнительные символы или незаконный JSON, которому нужна некоторая предварительная обработка. – bolav

+0

Собственно, это была моя ошибка. Мне нужно было настроить targetUrl (targetUrl: targetUrl + '/ auth). Теперь я получаю другую ошибку, но это может быть с моей стороны, а также: [1] _http_outgoing.js: 429 [1], если (this.finished) { [1]^ [1] [1] TypeError: Невозможно прочитать свойство «закончено» неопределенного [1] на OutgoingMessage.write (_http_outgoing.js: 429: 11) [1] на ServerResponse.res.end (server_es6.js: 60: 14) [1] на IncomingMessage.onend (_stream_readable.js: 490: 10) [1] на IncomingMessage.g (events.js: 260: 16) [1] at emitNone (events.js: 72: 20) . .. – csm232s