perl 允许使用带有Mojolicious::插件的CORS::SecureCORS

vngu2lb8  于 2023-02-05  发布在  Perl
关注(0)|答案(3)|浏览(143)

我是Mojolicious的新手,使用插件,尤其是SecureCORS。我如何在POST请求上允许CORS?
我设法允许CORS for GET使用以下行:

use Mojolicious::Lite;

app->plugin('SecureCORS');
app->routes->to('cors.origin' => '*');

我以为'cors.origin' => '*'允许CORS用于所有方法,但它只对GET有效。
也许有另一种或更好的方法来发送Access-Control-Allow-Origin头并允许所有POST、GET、PUT ...

tvz2xvvm

tvz2xvvm1#

坦率地说,我没有使用过SecureCors插件,但我在Mojolicious中开发REST API时遇到了同样的跨源问题。
注意:-我没有使用Mojolicious::lite应用程序。
您可能需要在您的启动子例程(如果不使用Mojolicious::Lite)下做一些或多或少类似的事情。

$self->hook(after_dispatch => sub { 
    my $c = shift; 
    $c->res->headers->header('Access-Control-Allow-Origin' => '*'); 
    $c->res->headers->access_control_allow_origin('*');
    $c->res->headers->header('Access-Control-Allow-Methods' => 'GET, OPTIONS, POST, DELETE, PUT');
    $c->res->headers->header('Access-Control-Allow-Headers' => 'Content-Type' => 'application/x-www-form-urlencoded');

});

希望能有所帮助。

a7qyws3x

a7qyws3x2#

定义为允许CORS,无论是在此处还是在父路线中。要为此路线设置CORS选项,至少必须为起始选项。

$r->get(…, {'cors.origin' => '*'}, …);
$r->any(…)->to('cors.origin' => '*');

允许在该航路上使用非简单(带飞行前)CORS

$r->cors(…);
0yg35tkg

0yg35tkg3#

我也很难让它工作,这不是POST和GET的问题,而是简单请求和预处理请求的问题。
加载SecureCORS时(plugin 'SecureCORS'),则它订阅after_render挂钩,并在每个请求结束时检查是否为当前(或父)路由(s),如果是CORS请求(Origin标头存在),以及Origin标头的值是否匹配cors.origin。如果匹配,则添加Access-Control-Allow-Origin,并且可能添加Access-Control-Allow-CredentialsAccess-Control-Expose-Headers
要处理preflighted请求,您需要使用cors快捷方式。它为指定的URL定义了一个OPTIONS路由。它从OPTIONS路由本身或目标路由中获取选项。它再次检查是否提供了cors.originOrigin头的值是否与cors.origin匹配,如果Access-Control-Request-Headerscors.headers匹配,则将Access-Control-Allow-OriginAccess-Control-Allow-Methods相加,并且可能将Access-Control-Allow-HeadersAccess-Control-Allow-CredentialsAccess-Control-Max-Age相加。
换句话说,要允许CORS处理所有请求,您需要执行app->routes->to('cors.origin' => '...', ...);,并对每个预处理请求执行app->routes->cors('/some/path')
下面是一个处理两个域(例如a.example.comb.example.com)请求的应用程序,当你打开http://a.example.com时,它会向b.example.com发出两个请求(一个简单的预调试):

#!/usr/bin/env perl
use Mojolicious::Lite -signatures;
plugin 'SecureCORS';

app->routes->to('cors.origin' => '*');

get '/' => sub ($c) {
  $c->render;
} => 'index';

get '/simple' => sub ($c) {
  $c->render(text => '');
};

app->routes->cors('/preflight');
del '/preflight' => {'cors.headers' => ''} => sub ($c) {
  $c->render(text => '');
};

app->start;
__DATA__

@@ index.html.ep
<!doctype html>
<html>
<body>
  <script>
    fetch('http://b.example.com/simple')
      .then(r => console.log(r))
      .then(() =>
        fetch('http://b.example.com/preflight', {method: 'DELETE'})
          .then(r => console.log(r))
      )
  </script>
</body>
</html>

docker下运行它所需的文件可以在here中找到。
这里的另一个问题是,为预照亮的路线定义cors.headers是有意义的,尽管它无论如何都能工作,但它会触发一个警告:
在/app/local/lib/perl 5/Mojolicious/Plugin/ www.example.com第118行的拆分中使用未初始化的值$opt{“头”}SecureCORS.pm。
虽然印前检查航线可以从目标航线收集cors.*选项(如果印前检查航线上没有cors.origin),但目标航线只能依赖于自身。也就是说,如果没有全局/父设置,并且您在印前检查航线上定义了cors.origin,则也应该在目标航线上这样做:

app->routes->cors('/preflight')->to('cors.origin' => '*');
del '/preflight' => {'cors.origin' => '*'} => sub ($c) {
  $c->render(text => '');
};

(Make确保在试验时禁用缓存,印前检查请求将被缓存。)

相关问题