问题 在Ionic应用程序中一起使用CORS和CSRF


我正在开发一个Android应用程序 离子框架 基于我开发的AngularJS网站使用 Jhipster。由于我已经在我的Web应用程序中运行了服务器代码,因此我选择Ionic作为UI工作并在需要时调用服务器,但我在开发环境中遇到了一些问题。

  1. 当我使用Ionic服务器运行我的应用程序时,我需要使用 CORS 向服务器发出请求。
  2. 我的Web应用程序是使用带有Spring Security的CSRF令牌开发的

我在用着 Apache CORS过滤器 这样配置:

private void initCORSFilter(ServletContext servletContext, EnumSet<DispatcherType> disps) {
    FilterRegistration.Dynamic corsFilter = servletContext.addFilter("cors", new CorsFilter());
    Map<String, String> parameters = new HashMap<>();
    parameters.put("cors.allowed.origins", "http://localhost:3000");
    parameters.put("cors.allowed.headers", "x-auth-token, x-requested-with, Content-Type, Accept, cache-control, x-csrf-token, Origin, Access-Control-Request-Method, Access-Control-Request-Headers");
    parameters.put("cors.allowed.methods", "POST, PUT, GET, DELETE");
    parameters.put("cors.exposed.headers", "Access-Control-Allow-Origin, Access-Control-Allow-Credentials");
    parameters.put("cors.support.credentials", "true");
    corsFilter.setInitParameters(parameters);
    corsFilter.addMappingForUrlPatterns(disps, true, "/*");
}

然后我用了 角CSRF-跨域 插件,以帮助跨域csrf请求:

.config(function ($urlRouterProvider,csrfCDProvider) {
    $urlRouterProvider.otherwise('/');
    //enable CSRF
    csrfCDProvider.setHeaderName('X-CSRF-TOKEN');
    csrfCDProvider.setCookieName('CSRF-TOKEN');
});

然后我尝试向我的本地服务器发送一个帖子请求:

angular.module('consamiApp')
.factory('Register', function ($resource) {
    //globalURL is https://localhost:8080
    return $resource(globalURL+'api/register', {}, {
    });
});
.
.
.
createAccount: function (account, callback) {
    var cb = callback || angular.noop;

    return Register.save(account,
        function () {
            return cb(account);
        },
        function (err) {
            this.logout();
            return cb(err);
    }.bind(this)).$promise;
}

但是我在firefox控制台中收到此消息:

跨源锁定请求:相同的源策略(同源策略)阻止读取远程资源 HTTPS://本地主机:8080 / API /寄存器。 (原因:CORS标题'Access-Control-Allow-Origin'不存在)

新的信息

当我提交我正在测试的表单时,AngularJs向服务器发出2个CORS请求:OPTIONS和POST,请求的结果是200 OK和403 Forbidden。这些是2个请求和响应的标头:

选项请求标头:

Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Origin: http://localhost:3000
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

选项答案标题:

Access-Control-Allow-Origin: http://localhost:3000
Content-Length: 0
Date: Tue, 30 Jun 2015 22:07:58 GMT
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=485A653AEAC8B8756DD3057BBF7FB862; Path=/; Secure; HttpOnly
CSRF-TOKEN=e8b3396c-63b2-47bf-9ad6-c1454628eb3b; Path=/
X-Application-Context: application:dev:8080
access-control-allow-credentials: true
access-control-allow-headers: origin,access-control-request-headers,x-requested-with,x-csrf-token,content-type,access-control-request-method,cache-control,x-auth-token,accept
access-control-allow-methods: POST
access-control-max-age: 1800

POST请求标题:

Host: localhost:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0
Accept: application/json, text/plain, */*
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/json;charset=utf-8
Referer: http://localhost:3000/
Content-Length: 109
Origin: http://localhost:3000
Cookie: _ga=GA1.1.123103160.1428358695; connect.sid=s%3AwD4KP4WBfhGO0JpFND3LpCzW.augts9fos9NMaZw%2B7XrNuilgaM8ocwSxaEUeDlIaVJ4; JSESSIONID=93200F4F4AFCEB28F10B130841808621
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

POST答案标题:

Content-Type: application/json;charset=UTF-8
Date: Tue, 30 Jun 2015 22:07:58 GMT
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked

有什么我没注意到的吗?该 Ionic的官方博客 我说在部署应用程序时我不应该担心CORS问题,但至少对于测试来说,我真的需要解决这个问题。你能给我任何选择吗?


8029
2018-06-25 23:02


起源



答案:


你安装和配置了吗? cordova插件白名单 自Cordova 5.0.0以来,这对于CORS查询是必需的

安装它:

cordova plugin add cordova-plugin-whitelist

配置config.xml

您可以使用*保留当前设置,或更改限制性规则

添加一个HTML政策 在index.html上,您还应添加一个策略。 要授权一切,这里是:

 <meta http-equiv="Content-Security-Policy" content="default-src *;
 style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'
 'unsafe-eval'"

要验证您是否正确安装了插件,请使用以下命令将其检入您的cordova插件:

cordova plugins 

你应该看到cordova-plugin-whitelist。

其次,您可能需要添加 withCredentials 你的$http (以及$资源)查询:

  .config(function($httpProvider) {
        $httpProvider.defaults.withCredentials = true;
    });

5
2018-06-30 11:40



如果您没有使用离子来生成项目,那么@aofevre很可能是正确的。如果你使用离子,他们现在将插件包含在项目中。 - Jess Patton
你在哪里看到过离子包装cordova插件白名单?到目前为止,我看到它应该手动安装(docs.ionic.io/v1.0/docs/cordova-whitelist)。 - aorfevre
我已将cordova命令添加到响应中以验证白名单插件是否已正确安装;但我还是找不到任何迹象表明离子是否包含此插件;) - aorfevre
如果你运行离子启动测试空白(启动一个新的空白离子项目),请查看插件文件夹! BAM!白名单插件就在那里 - Jess Patton
正如@JessPatton所说,白名单插件默认安装在Ionic中。我添加了元标记,但结果是一样的。我在问题中添加了请求的标题,也许有些东西我没有看到。 - brevleq


答案:


你安装和配置了吗? cordova插件白名单 自Cordova 5.0.0以来,这对于CORS查询是必需的

安装它:

cordova plugin add cordova-plugin-whitelist

配置config.xml

您可以使用*保留当前设置,或更改限制性规则

添加一个HTML政策 在index.html上,您还应添加一个策略。 要授权一切,这里是:

 <meta http-equiv="Content-Security-Policy" content="default-src *;
 style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'
 'unsafe-eval'"

要验证您是否正确安装了插件,请使用以下命令将其检入您的cordova插件:

cordova plugins 

你应该看到cordova-plugin-whitelist。

其次,您可能需要添加 withCredentials 你的$http (以及$资源)查询:

  .config(function($httpProvider) {
        $httpProvider.defaults.withCredentials = true;
    });

5
2018-06-30 11:40



如果您没有使用离子来生成项目,那么@aofevre很可能是正确的。如果你使用离子,他们现在将插件包含在项目中。 - Jess Patton
你在哪里看到过离子包装cordova插件白名单?到目前为止,我看到它应该手动安装(docs.ionic.io/v1.0/docs/cordova-whitelist)。 - aorfevre
我已将cordova命令添加到响应中以验证白名单插件是否已正确安装;但我还是找不到任何迹象表明离子是否包含此插件;) - aorfevre
如果你运行离子启动测试空白(启动一个新的空白离子项目),请查看插件文件夹! BAM!白名单插件就在那里 - Jess Patton
正如@JessPatton所说,白名单插件默认安装在Ionic中。我添加了元标记,但结果是一样的。我在问题中添加了请求的标题,也许有些东西我没有看到。 - brevleq


当我编辑问题并看到带有HttpOnly子句的OPTIONS响应头时,我开始认为问题出在我在开发环境中使用的自签名证书。

Set-Cookie:JSESSIONID = 485A653AEAC8B8756DD3057BBF7FB862;路径= /;安全;仅Http

所以我决定在Web服务器中禁用https协议并且它正常工作。谢谢你的帮助。


3
2018-06-26 01:44



如何设置此JSESSIONID - Hema


CORS规范是全有或全无。它只支持*,null或确切的域: http://www.w3.org/TR/cors/#access-control-allow-origin-response-header

我认为您不能将端口号指定为其值。


1
2018-06-30 03:50



我逃脱了:端口角色,据说 angularjs $ resource doc - brevleq