Heim  >  Artikel  >  PHP-Framework  >  Teilen Sie Ideen zur domänenübergreifenden Problemlösung von thinkphp withCredentials

Teilen Sie Ideen zur domänenübergreifenden Problemlösung von thinkphp withCredentials

藏色散人
藏色散人nach vorne
2021-03-11 11:32:342075Durchsuche

Die folgende Tutorial-Kolumne von thinkphp wird Ihnen Ideen zur domänenübergreifenden Problemlösung von thinkphp mit Anmeldeinformationen vorstellen. Ich hoffe, dass es Freunden in Not hilfreich sein wird!

Ich werde hier nicht näher darauf eingehen, was domänenübergreifend ist. Hier spreche ich hauptsächlich über thinkphp5.1 und spreche zunächst über die allgemeine Lösungsidee , weil das Front-End von mir selbst geschrieben wurde, habe ich in In der axios-Konfiguration Folgendes eingestellt

withCredentials: true // Cookie bei domänenübergreifender Anfrage sendenaxios配置中, 我设置了如下

withCredentials: true // 跨域请求时发送cookie

// 创建一个axios
const service = axios.create({
  baseURL: URL , 
  withCredentials: true, // 跨域请求时发送cookie
  timeout: 5000 // request timeout
})

在后端的配置中,配置的是

header("Access-Control-Allow-Origin: *");

故而抛出了这样一个错误

Access to XMLHttpRequest at 'http://store.ink/admin/me?sid=lbn3mpacfb3k1mbehnk9qh8kf3' from origin 'http://vue-admin-web.ink' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

意思大概为 设置 withCredentialstrue 时, origin 是不允许为 *的, origin必须设置为来源的地址

也就是 http://a.com 请求 http://b.com 的时候, http://a.com 必须设置origin 为 http://b.com 才能通过

最后参阅配置如下

 $origin = $_SERVER['HTTP_ORIGIN'] ?? '*';
        header("Access-Control-Allow-Origin: $origin");
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With');
        header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
        header('Access-Control-Max-Age: 1728000');

当然, 为 * 的时候也可以这样

header("Access-Control-Allow-Origin: *");
        header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With');
        header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
        header('Access-Control-Max-Age: 1728000');

首先 定义个中间件 php think make:middleware CrossDomain

<?php
namespace app\http\middleware;

use think\Response;


class CrossDomain
{
    public function handle($request, \Closure $next)
    {
        $origin = $_SERVER[&#39;HTTP_ORIGIN&#39;] ?? &#39;*&#39;;
        header("Access-Control-Allow-Origin: $origin");
        header(&#39;Access-Control-Allow-Credentials: true&#39;);
        header(&#39;Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With&#39;);
        header(&#39;Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE&#39;);
        header(&#39;Access-Control-Max-Age: 1728000&#39;);

        return $next($request);
    }
}

router.php

Route::group(&#39;&#39;, function (){
    ....
    这里写路由
    ....
})->middleware(['CrossDomain']);

然后又有一个新问题

因为如上是走的路由文件,当请求的url

....
public function render(Exception $e)
{
    # 这里来处理跨域问题 
    $origin = $_SERVER['HTTP_ORIGIN'] ?? '*';
    header("Access-Control-Allow-Origin: $origin");
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-Requested-With');
    header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE');
    header('Access-Control-Max-Age: 1728000');
    $type = request()->isAjax() ? 'json' : "html";
    $response = \think\response\Json::create([], $type, 200, []);
    return $response; # response  // 在异常处理接管中,必须返回的是一个人response响应, 而不是 `throw new `抛出一个响应
}
...
In der Backend-Konfiguration, Die Konfiguration ist

rrreee

, daher wurde ein solcher Fehler

rrreee

ausgegeben. Die Bedeutung ist wahrscheinlich, dass beim Setzen von withCredentials auf true der Ursprung nicht sein darf * und der Ursprung müssen auf die Quelladresse eingestellt sein

d. h. http Wenn ://a.com http://b.com anfordert, muss http://a.com den Ursprung auf http setzen ://b.com zu bestehen

Beziehen Sie sich abschließend auf die Konfiguration wie folgt

rrreee
Natürlich kann dies auch getan werden, wenn *
rrreee

Definieren Sie zunächst eine Middleware php think make :middleware CrossDomainrrreeeIn router.php

rrreee

Dann gibt es ein neues Problem

Weil die Routing-Datei wie oben verwendet wird, wenn die angeforderte url stimmt mit der Route überein, es wird domänenübergreifende Middleware verwendet. Wie jeder weiß, initiieren Methoden wie delete und put im Voraus eine Optionsanforderung, was bedeutet, dass die Routing-Datei nicht mit der Domäne übereinstimmt Middleware kann nicht verwendet werden. Deshalb:
🎜 Definieren Sie eine Fehlerausnahme, die https://www.kancloud.cn/manual/ thinkphp5_1/354092#_42🎜rrreee🎜complete übernimmt. 🎜🎜🎜🎜🎜Verwandte Empfehlungen: 🎜Die neuesten 10 Thinkphp-Video-Tutorials🎜🎜🎜🎜

Das obige ist der detaillierte Inhalt vonTeilen Sie Ideen zur domänenübergreifenden Problemlösung von thinkphp withCredentials. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen