CORS AngularJS不使用POST或DELETE发送Cookie /凭据但是可以正常
我有一个ExpressJS API服务器和一个在本地开发中运行的带有AngularJS应用程序的ExpressJS.
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发送api请求 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已将Restanguarl配置为正确发送凭据我相信: 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,X-Requested-With Access-Control-Allow-Methods:GET,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. 这是一个飞行前选项请求的示例(不应该发送任何凭据) Request URL:http://api.rsm.local:3001/api/v1/articles Request Method:OPTIONS Status Code:200 OK Request Headers Accept:*/* Accept-Encoding:gzip,sdch Accept-Language:en-US,en;q=0.8 Access-Control-Request-Headers:accept,content-type Access-Control-Request-Method:POST Connection:keep-alive Host:api.rsm.local:3001 Origin:http://rsm.local:3000 Referer: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 Response Headers Access-Control-Allow-Credentials:true Access-Control-Allow-Headers:Accept,OPTIONS Access-Control-Allow-Origin:http://rsm.local:3000 Allow:GET,HEAD,TRACE,COPY,LOCK,MKCOL,MOVE,PROPFIND,PROPPATCH,UNLOCK,REPORT,MKACTIVITY,CHECKOUT,MERGE,M-SEARCH,NOTIFY,SUBSCRIBE,UNSUBSCRIBE,PATCH Connection:keep-alive Content-Length:154 Content-Type:text/html; charset=utf-8 Date:Fri,06 Dec 2013 15:04:23 GMT 所以这个选项请求似乎说“是接受POST并且Origin URL匹配” 但是subsequest 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,*/* 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 ... ... ... 这里和网上的其他地方有许多线程似乎都建议使用我的配置,但仍然没有使用POST / DELETE发送凭据. 我现在几乎陷入困境,希望另一双眼睛看到什么? 为什么GET会好,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()解决方案. 干杯. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |