Stripe错误:拒绝执行内联脚本,因为它违反了CSP。

huangapple go评论65阅读模式
英文:

Stripe error : Refused to execute inline script because it violates the CSP

问题

Here is the translated portion of your text:

我有一个使用VueJS3前端和Symfony后端构建的应用程序存在问题。我正在使用它来进行支付和其他交易。当客户下订单时,会发出一个AJAX HTTP请求到我的API,我的STRIPE自定义类会构建带有整个订单信息的结帐会话,如下所示:

public function startPayment($cartData, $orderId, Request $request, $userId, $totalQuantity){
    // 计算折扣
    $discount = 0;
    if($totalQuantity >= 6){
        $discount = 0.2;
    } else if($totalQuantity >= 3){
        $discount = 0.1;
    }
    $metadata = [
        'user_id' => $userId,
    ];
    $checkout_session = Session::create([
        'line_items' => [
            array_map( fn(array $product) => [
                'quantity' => $product['quantity'],
                'price_data' => [
                    'currency' => 'EUR', 
                    'product_data' => [
                        'name' => 'photo'
                    ],
                    'unit_amount' => $product['price'] * 100 * (1 - $discount),
                ] 
            ], $cartData )
        ],
        'payment_intent_data' => [
            'description' => 'Description de votre commande',
        ],
        'mode' => 'payment',
        'success_url' => "http://localhost:5173/success/" .  $orderId ,
        'cancel_url' => "http://localhost:5173/failure",
    ]);
    return $checkout_session;
}

好的,然后我捕获会话ID,它将包含在我的HTTP响应中的有效载荷中。最后,我将客户重定向到付款页面。

if (cart.length > 0) {
  orderService.makeOrder(formdata)
    .then((res) => {
      cartStore.trashCart();
      console.log(res.data);
      stripe.redirectToCheckout({
        sessionId: res.data
      });
    })
    .catch((err) => {
      console.log(err);
      if (errorStatus == 404) {
        alert(error.message);
        router.push({ 'name': 'user-dashboard' })
      }
    });
} else {
  alert('Votre panier est vide !');
}

如您所见,我已经使用了多种重定向方法,例如window.location.replace,window.open等。

顺便说一下,无论是通过检索会话ID还是URL,我始终都会出现与CSP策略相关的相同错误消息:

VM15:1 拒绝执行内联脚本,因为它违反了以下内容安全策略指令:"script-src 'self' https://js.stripe.com 'sha256-qfab1QOuLBUBGJ+fPSXEniBt3ROj7X2Q4d7JLWBSVcU=' 'sha256-6DwLXTwuIAiFiQ/xN6K2pNzcz78YimIo/S8e2fsEfIw=' 'sha256-qzwF6Hw52bvaC7XI8bXNymM/G1VA5sKAddevTw8+gj8='". 要启用内联执行,需要使用"unsafe-inline"关键字、哈希('sha256-FDyPg8CqqIpPAfGVKx1YeKduyLs0ghNYWII21wL+7HM=')或一个nonce('nonce-...')。

我尝试在我的应用程序入口点(index.html)中插入了一个元素,如下所示:

<meta http-equiv="Content-Security-Policy" content="script-src 'self' https://js.stripe.com/v3/ https://cdnjs.cloudflare.com 'unsafe-inline'">

我承认我不太理解"hash"或"nonce",特别是与VueJS集成相关的部分。

奇怪的是,在开发中付款可以正常工作...而且在我的脚本中没有任何"script-inline"可能引发这种问题的部分。

英文:

i've got a problem witch an application build with VueJS3 front side and Symfony on the backend.I am using to proceed paiement and others transactions. When the client makes an order, an AJAX http request goes to my api, and ma STRIPE custom class build the checkout session with the whole order informations like this :

public function startPayment($cartData, $orderId, Request $request, $userId, $totalQuantity){

        // calcul de la r&#233;duction
        $discount = 0;
        if($totalQuantity &gt;= 6){
            $discount = 0.2;
        } else if($totalQuantity &gt;= 3){
            $discount = 0.1;
        }


        $metadata = [
            &#39;user_id&#39; =&gt; $userId,
        ];

            $checkout_session = Session::create([
            &#39;line_items&#39; =&gt; [
                    array_map( fn(array $product) =&gt; [
                        &#39;quantity&#39; =&gt; $product[&#39;quantity&#39;],
                        &#39;price_data&#39; =&gt; [
                            &#39;currency&#39; =&gt; &#39;EUR&#39;, 
                            &#39;product_data&#39; =&gt; [
                                &#39;name&#39; =&gt; &#39;photo&#39;
                            ],
                            &#39;unit_amount&#39; =&gt; $product[&#39;price&#39;] * 100 * (1 - $discount),
                            // &#39;description&#39; =&gt; &#39;R&#233;duction de &#39; . ($discount * 100) . &#39;% appliqu&#233;e pour un total de &#39; . ($product[&#39;price&#39;] * $discount * $product[&#39;quantity&#39;]) . &#39; EUR&#39;,
                        ] 
                    ], $cartData )
                ],
                &#39;payment_intent_data&#39; =&gt; [
                    &#39;description&#39; =&gt; &#39;Description de votre commande&#39;,
                  ],
            &#39;mode&#39; =&gt; &#39;payment&#39;,
            &#39;success_url&#39; =&gt; &quot;http://localhost:5173/success/&quot; .  $orderId ,
            &#39;cancel_url&#39; =&gt; &quot;http://localhost:5173/failure&quot;,
            // &#39;metadata&#39; =&gt; $metadata,
        ]);

        return $checkout_session;
    }

Ok then I catch the session ID which will include in the payload on my http response to the front-end. Finally, I redirect the client to the payment page.

    if (cart.length &gt; 0) {

      orderService.makeOrder(formdata)
        .then((res) =&gt; {
          cartStore.trashCart();
          // window.location.replace(res.data);
          // res.redirect(res.data)
          // window.open(res.data, &#39;_blank&#39;);
          console.log(res.data);
         
          stripe.redirectToCheckout({
            sessionId: res.data
          });
        }
        )
        .catch((err) =&gt; {
          // console.log(err.response.data);
          // let error = err.response.data;
          // let errorStatus = error.status;
          console.log(err);
          if (errorStatus == 404) {
            alert(error.message);
            router.push({ &#39;name&#39;: &#39;user-dashboard&#39; })
          }
        }
        );
    } else {
      alert(&#39;Votre panier est vide !&#39;);
    }

As you can see i've made a few tests with many redirections methods like window.location.replace, window.open....

By the way, whether by retrieving the session id or the url, I always have the same follwing error message that appears relating to the CSP policy :

VM15:1 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' https://js.stripe.com 'sha256-qfab1QOuLBUBGJ+fPSXEniBt3ROj7X2Q4d7JLWBSVcU=' 'sha256-6DwLXTwuIAiFiQ/xN6K2pNzcz78YimIo/S8e2fsEfIw=' 'sha256-qzwF6Hw52bvaC7XI8bXNymM/G1VA5sKAddevTw8+gj8='". Either the 'unsafe-inline' keyword, a hash ('sha256-FDyPg8CqqIpPAfGVKx1YeKduyLs0ghNYWII21wL+7HM='), or a nonce ('nonce-...') is required to enable inline execution.

I've tried to insert a meta element in the entry point of my application ( index.html ) like this :
meta http-equiv="Content-Security-Policy" content="script-src 'self' https://js.stripe.com/v3/ https://cdnjs.cloudflare.com 'unsafe-inline'">

and i admit that i don't really inderstand the "hash" or " nonce" specialy with VueJS integration.

Strangely, the payment works in dev... and don't have any " script-inline" in my script which could occurs this kind of problem

答案1

得分: 1

首先,您有一些内联脚本。这可能来自第三方包。请注意,内联事件处理程序(例如onclick等)也算作内联脚本,除非您想在内容安全策略(CSP)方面进行高级处理,否则唯一的选择是将它们替换为事件监听器。因此,首先您应该尝试识别内联脚本以及其来源。通常,在错误消息中会有一个链接,可以告诉您问题所在。如果内联代码是静态的,您应该能够成功添加一个哈希值。

您已将CSP添加为元标记。这个CSP具有与错误消息中不同的script-src指令。这意味着您有两个策略,任何内容都需要同时通过两者。您需要识别其他策略的设置位置(它会在响应标头中找到),并进行修改。

英文:

First of all you have some inline script. This could come from a third party package. Note that inline event handlers (onclick etc) also counts as inline script, and unless you want to get advanced with CSP, the only option is to replace them with event listeners. So first you should try to identify the inline script and where it comes from. There is usually a link in the error message that will show you what the problem is. If the inline code is static, you should be able to successfully add a hash.

You have added your CSP as a meta tag. This CSP has a script-src directive that is different from the one in the error message. This means that you have two policies, and any content will need to pass both. You will need to identify where the other policy is set (you will find it in a response header) and modify it.

答案2

得分: 0

我终于找到了解决方法。错误是由于使用VueJsDevTools作为Chrome依赖项引起的。因为该插件注入了JavaScript代码来检查应用程序状态,所以可能会引发安全问题,特别是与内容安全策略有关。谢谢。

英文:

I've finally found a way to resolve that. The error was caused by using VueJsDevTools as a Chrome dependency. Because the plugin injects JavaScript code to check the application state, it can raise security problems, specifically with the Content Security Policy. Thanks.

huangapple
  • 本文由 发表于 2023年5月7日 01:07:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76190134.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定