2017-01-06 39 views
1

我正在使用Node.js作爲服務器端和Angular 2作爲前端的示例應用程序。Node JS/Angular 2應用程序,ForbiddenError:無效的csrf標記

爲了防止CSRF攻擊,我曾用 「csurf」 中間件 下面是相關的代碼來設置中間件

// cookie parser 
app.use(cookieParser()); 

// express session middleware , this should be after cookie parser 
app.use(session({secret:'clickclick'})); 

app.use(session({ 
secret: 'clickclick', 
cookie: { 
    path:'/', 
    httpOnly:true, 
    maxAge:null 
} 
})); 

// CSRF middleware 
app.use(csurf()); 

下面node.js的路線集 「_csrf」 頭

router.get('/:id/products/:pid' , wrap(function *(req , res , next) { 

try 
{ 
    console.log('url' , req.url); 
    res.setHeader('_csrf', req.csrfToken()); 
    let product = yield category.getProduct(req , res , next); 
    res.send(product); 
} 
catch(err) 
{ 
    res.status(500).send(err); 
} 

})) 

上面提到的路線'/:id/products /:pid'從我的下面的Angular 2服務方法調用

// Get Product 
GetProduct(id:string, pid:string):Observable<Product> { 

    return this.http.get('./categories/' + id + '/products/' + pid) 
        .map(data =>{ let headers:Headers = data.headers; 
            this.csrfToken = headers.get('_csrf') ; 
           return data.json() }) 
        .catch(this.handleError); 
} 

此方法將從服務器返回的_csrf標頭分配給「this.csrfToken」屬性。

當下面的服務方法發出AJAX POST請求時,它使用上述方法設置的「this.csrfToken」屬性值並設置標頭「_csrf」的值。

// Add an item to cart 
AddTocart(product:Product) 
{ 
    let item = { pid:product._id , name:product.name , price:product.price , qty:1 , total:product.price }; 
    //this.cart.push(item); 

    // make an AJAX call to save the item in server session 
    let url = './cart/add'; 
    let headers = new Headers({'Content-Type':'application/json' , '_csrf':this.csrfToken}); 
    let requestOptions = new RequestOptions({headers:headers}); 

    this.http.post(url , item , requestOptions) 
      .map(data => {         
          this.cart.push(item); 
          } 
      ) 
      .catch(this.handleError) 
      .subscribe(data => { });     

} 

以下是GetProduct服務方法的Response Header。 enter image description here

下面是「AddTocart」服務方法的請求頭。

enter image description here

任何想法是什麼原因造成 「ForbiddenError:無效CSRF令牌」 的錯誤。 如果我需要提供更多信息或者提供的信息不明確,請讓我知道。

回答

0

我知道這是一個較老的問題,但我在此添加這個以防萬一有人在將來遇到它。在一個類似的項目上工作,遇到同樣的錯誤,我通過在POST請求中添加一個XSRF-TOKEN頭來修復它,值爲$.cookie("XSRF-TOKEN")(使用jquery和cookies插件)。根據文檔,_csrf也應該可以工作。

the project page

The default value is a function that reads the token from the following locations, in order: 

req.body._csrf - typically generated by the body-parser module. 
req.query._csrf - a built-in from Express.js to read from the URL query string. 
req.headers['csrf-token'] - the CSRF-Token HTTP request header. 
req.headers['xsrf-token'] - the XSRF-Token HTTP request header. 
req.headers['x-csrf-token'] - the X-CSRF-Token HTTP request header. 
req.headers['x-xsrf-token'] - the X-XSRF-Token HTTP request header. 

據我所知道的,錯誤似乎來自POST/PUT請求包括正確的Cookie,但的NodeJS/csurf是不是找過來的。

在您的具體情況下,_csrf應與購物車項目一起位於請求正文中,或者標題應重命名爲csrf-token或其他選項之一。