CORS AngularJS未发送带有POST或DELETE的Cookie/凭证,但得到确认

CORS AngularJS未发送带有POST或DELETE的Cookie/凭证,但得到确认,angularjs,express,cors,Angularjs,Express,Cors,我有一个ExpressJSAPI服务器和一个ExpressJS w/AngularJS应用程序在本地开发环境中运行 CORS GET请求工作正常,但POST和DELETE不会发送任何cookie(凭据) 我尝试了各种配置选项,但应用程序从未发送POST或DELETE的凭据 我希望有人熟悉这一点,并可能看到我的错误 我在/etc/hosts中设置了两个本地域: 127.0.0.1 rsm.local 127.0.0.1 api.rsm.local 所以http://rsm.local正在向htt

我有一个ExpressJSAPI服务器和一个ExpressJS w/AngularJS应用程序在本地开发环境中运行

CORS GET请求工作正常,但POST和DELETE不会发送任何cookie(凭据)

我尝试了各种配置选项,但应用程序从未发送POST或DELETE的凭据

我希望有人熟悉这一点,并可能看到我的错误

我在/etc/hosts中设置了两个本地域:

127.0.0.1 rsm.local
127.0.0.1 api.rsm.local
所以
http://rsm.local
正在向
http://api.rsm.local

AngularJS正在使用Restangular

会话存储在域的MongoDB中,具有
.rsm.local
,因此两台服务器都可以读取cookie

客户端应用程序和api服务器都使用相同的cookie密钥和密码

app.use(express.session({
key: config.cookie_key,
secret: config.cookie_secret,
cookie: {
    domain:'.rsm.local',
    expires: config.cookie_expire
},
store: new mongoStore({
    url: config.database,
    collection: 'sessions',
    auto_reconnect: true
})
}));
在两个应用程序之间共享会话状态正常时,这似乎工作正常

API服务器是用标准和我认为正确的CORS头设置的:

app.all('/api/*', function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://rsm.local:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
res.setHeader("Access-Control-Allow-Headers", "Accept, Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
客户端应用AngularJS已重新配置为正确发送凭据我相信:

angular.module('rsm').config(function (RestangularProvider) {

RestangularProvider.setBaseUrl('http://api.rsm.local:3001/api/v1');

RestangularProvider.setDefaultHttpFields({
withCredentials: true,
useXDomain : true
});

});
因此,GET请求一切正常(例如列出所有请求和列出一个请求):

下面是一个GET请求的示例(无飞行前请求),我们可以看到cookie是跨域发送的,当CORS都正确排列时,响应工作:

Request URL:http://api.rsm.local:3001/api/v1/articles
Request Method:GET
Status Code:200 OK

Request Headers
GET /api/v1/articles HTTP/1.1
Host: api.rsm.local:3001
Connection: keep-alive
Accept: application/json, text/plain, */*
Origin: http://rsm.local:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Referer: http://rsm.local:3000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: rsm.sid=s%3A84buSYdgwFPljnBdSdXZhGpe.z86NeNf%2F%2FT9Rn2t9MAaf3%2B4YAnXGsvSbb3nAh0spqZw; XSRF-TOKEN=JtmKfwWOhxxHxtyYR%2B2HdPSfW8e8T7ofUeROE%3D

Response Headers
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Accept, Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Origin:http://rsm.local:3000
Connection:keep-alive
Content-Length:914
Content-Type:application/json; charset=utf-8
Date:Fri, 06 Dec 2013 15:04:53 GMT
但是,当使用相同的配置执行POST或DELETE时,cookie永远不会被发送

以下是飞行前选项请求的示例(不应发送任何凭证)

所以这个选项请求似乎说“是的,接受POST,并且源URL匹配”

但是subquest POST请求缺少Cookie

Request URL:http://api.rsm.local:3001/api/v1/articles

Request Headers
POST http://api.rsm.local:3001/api/v1/articles HTTP/1.1
Accept: application/json, text/plain, */*
Referer: http://rsm.local:3000/
Origin: http://rsm.local:3000
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko)    Chrome/31.0.1650.63 Safari/537.36
Content-Type: application/json;charset=UTF-8
Request Payload
...
...
...
web上的许多线程似乎都建议使用我拥有的配置,但仍然没有随POST/DELETE发送的凭据

我现在几乎被困住了,希望另一双眼睛能看到什么

为什么得到的是OK而不是POST

我在使用Chrome和FireFox的Ubuntu工作站上,两者都不发送凭据


谢谢。

我找到了一个适合我的解决方案

我使用的是ExpressJS csrf()、passortjs和CORS头的组合

csrf()失败,这会破坏其他一切,导致浏览器在控制台中显示没有凭据的标题

解决方案是在connect的defaultValue函数中再添加一个请求类型查找

我已经创建了一个新的,并像这样使用它:

function csrfValue(req) {
        return (req.body && req.body._csrf)
            || (req.query && req.query._csrf)
            || (req.headers['x-csrf-token'])
            || (req.headers['x-xsrf-token'])
            || (req.cookies['XSRF-TOKEN']);
    }

app.use(express.csrf({value: csrfValue}));
这使一切工作正常

我还发现,使用Restangular,我可以为x-xsrf-token设置自定义头,但只有Chrome可以设置,FireFox不能

所以我决定使用csrfValue()解决方案


干杯。

可能会有帮助:我非常确定我已经涵盖了所有这些要点。已设置withCredientials,.domain.com通配符类型会话cookie集。
function csrfValue(req) {
        return (req.body && req.body._csrf)
            || (req.query && req.query._csrf)
            || (req.headers['x-csrf-token'])
            || (req.headers['x-xsrf-token'])
            || (req.cookies['XSRF-TOKEN']);
    }

app.use(express.csrf({value: csrfValue}));