【问题标题】:Storing Token from API w/ Express http-proxy使用 Express http-proxy 从 API 存储令牌
【发布时间】:2016-05-26 23:49:06
【问题描述】:

我正在设置一个通用的 React 应用程序并使用 this project 作为基础。我成功地将请求(使用http-proxy)代理到我的 Laravel 后端。但是,我是 Nodejs 的新手,我不知道如何将 JWT 从代理服务器安全地存储到客户端的最佳方法。

我最初的想法是将令牌存储到 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});
});

【问题讨论】:

    标签: javascript node.js express cookies proxy


    【解决方案1】:

    鉴于 laravel 中 auth 端点的响应是这样的:

    { 
        "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);
            }
    
        }
    });
    

    【讨论】:

    • 看起来我遇到的唯一问题是 var parsed = JSON.parse(body);抛出错误:意外的令牌。来自服务器的响应是 json。我也尝试过 JSON.parse(body.toString('utf8')),但我仍然得到同样的错误
    • 请发布body 是什么。 console.log(body); 可能是一些额外的字符,或者需要一些预处理的非法 JSON。
    • 其实那是我的错。我需要调整 targetUrl (targetUrl: targetUrl + '/auth')。现在我遇到了一个不同的错误,但这也可能是我的问题:[1] _http_outgoing.js:429 [1] if (this.finished) { [1] ^ [1] [1] TypeError: Cannot在 OutgoingMessage.write (_http_outgoing.js:429:11) [1] 在 IncomingMessage.onend (_stream_readable .js:490:10) [1] 在 IncomingMessage.g (events.js:260:16) [1] 在 emitNone (events.js:72:20) ...
    • _http_outgoing.js 属于哪个模块?这是你的剧本吗?
    猜你喜欢
    • 1970-01-01
    • 2018-12-07
    • 2016-02-14
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    相关资源
    最近更新 更多