2014-06-14 12 views
2

我會通過本教程爲建設一個節點API POST請求:如何阻止來自不同產地的節點

http://scotch.io/tutorials/javascript/build-a-restful-api-using-node-and-express-4

他們經歷如何測試與getpostman.com POST請求。

不過 - 我不希望我的應用程序響應後從不同的域請求。我只希望它響應來自我的域(不是瀏覽器)的Rails發佈的請求。我如何停止接受來自外國來源的這些請求,但是允許來自我的Rails服務器的請求?

我試着像中間件下面是我從this鏈接找到。但沒有奏效。這一定很容易。任何線索?

router.all('/', function(req, res, next) { 
    res.header("Access-Control-Allow-Origin", "https://www.example.com"); 
    res.header("Access-Control-Allow-Headers", "X-Requested-With"); 
    res.header("Access-Control-Allow-Methods", "POST GET"); 
    res.header("X-Frame-Options", "ALLOWALL"); 
    res.header("Access-Control-Allow-Credentials", "true"); 
    next(); 
}); 

回答

4

您可以檢查其中的請求通過檢查客戶端的IP作爲described here來了。然後,您可以將其與允許的地址列表進行比較,或者執行反向DNS查找以檢查域。應謹慎實施後一種方法,首先解決允許的域並檢查一組靜態IP地址可能會更好。

這裏是一個小模塊,其中出口中間件將恰恰如此(甚至沒有測試過一次)。

// allowed is an array of allowed hosts 
// readyCb is an optional function that will be called 
// once all host names have been resolved 
module.exports = function(allowed, readyCb) { 
    // Resolve all domains 
    var ips = []; 
    var remaining = allowed.length; 
    allowed.forEach(function(host) { 
    if(/^[.0-9]+$/.test(host)) { 
     // Should be an IP address 
     ips.push(host); 
     remaining--; 
     if(!remaining && readyCb) readyCb(); 
    } else { 
     // Resolve the host name 
     // Adapt this if you want IPv6 support 
     require('dns').resolve(host, 'A', function(err, addresses) { 
     remaining--; 
     if(!err) { 
      addresses.forEach(function(ip) { ips.push(ip); }); 
     } else { 
      // Handle the error, either using an additional callback 
      // or by collecting all errors and submitting them to 
      // readyCb 
     } 
     if(!remaining && readyCb) readyCb(); 
     }); 
    } 
    }); 
    return function(req, res, next) { 
    var clientIp = req.ip; 
    // Check if the address is allowed 
    if(ips.indexOf(clientIp) == -1) { 
     res.end(403, 'Remote host is not allowed to use the API'); 
    } else { 
     next(); 
    } 
    }; 
}; 

的瀏覽器原來的答覆請求

使用這樣的中間件:

var url = require('url'); // standard node module 

function(req, res, next) { 
    var ref = req.headers.referer; 
    if(ref) { 
    // We got a referer 
    var u = url.parse(ref); 
    if(u && u.hostname === 'myhost.com') { 
     // Correct host, process the request 
     return next(); 
    } 
    } 
    // Send some kind of error 
    res.send(403, 'Invalid origin'); 
} 

請注意,參照標頭可能不可用。修改上面的代碼片段以對這種情況做出反應。

+0

每當我試圖從getpostman.com或從我的軌道服務器POST請求,u.hostname爲空。另外,有人可以僞造主機名? – bumpkin

+0

澄清 - 我們將從rails發送發佈請求,而不是直接從瀏覽器發送(更新後的問題)。 – bumpkin

相關問題