web-dev-qa-db-ja.com

Laravel SanctumおよびAngular

概観

私はLaravelローカルでホストされているパワードAPI http://tenant.api.hydrogen.local とAngular 9.2 SPAこれは http:// localhost:81 で提供されています。私は最近Laravel認証用の聖域をインストールし、SPAの指示に従いました docs しかし、CSRFトークンはSPAからのリクエストに添付されていないため、CSRFトークンの不一致エラーを受け取ります。

手順に沿って、次にログインを試みる前に//abc.api.hydrogen.local/sanctum/csrfを最初に呼び出します。

this.http.get('sanctum/csrf-cookie')
    .pipe(
        switchMap(result => this.http.post('auth/login', {'email': email, 'password': password}))
    );

注:リクエストURLの前にapi url '//abc.api.hydrogen.local/'を付加するインターセプターがあります。 「sanctum/csrf-cookie」は「//abc.api.hydrogen.local/sanctum/csrf-cookie」になります

Sanctum/csrf-cookieからの応答は、予期されるヘッダーとともに返されます。

Access-Control-Allow-Credentials: true
Set-Cookie: XSRF-TOKEN=eyJpdiI6Ilc3UkRLR1BSZ29TWVh3ZWZEQ3Y4aGc9PSIsInZhbHVlIjoiRUZBZXNFWTlZbWo5QWhIeWsrRmpjNUZVWkExSGtaT1hzUTVnSXpoaGQ4c3dFc2VLNjZsUHlUVWFmbG1uVVdKZSIsIm1hYyI6ImU1ZTAxNGFmMjAwNWRiMDhiODFjMGZhYTljYmU1NmRjYTUzYTNmNDJjNWM3YmQyM2FkY2I2OGYwNjYzNGU2MjkifQ%3D%3D; expires=Thu, 30-Apr-2020 13:35:06 GMT; Max-Age=7200; path=/; domain=localhost
Access-Control-Allow-Origin: http://localhost:8100

しかし、ブラウザコンソールを見ると、ストレージ> Cookieに何も設定されていません。さらに、 `login/'への後続の呼び出しにCookieが添付されておらず、CSRFトークンの不一致エラーを受け取ります。

私は同様の問題を詳述する多数の投稿を読み、以下を含むそれらの推奨事項と構成を実装しました:

Laravel API

  • .envでSESSION_DRIVER = cookieおよびSESSION_DOMAIN = localhost:8100を設定しました
  • Config/sanctumで、ステートフルドメインにlocalhost:8100を追加しました
  • Config/corsでsupports_credentials = trueを設定し、すべてのパス、ヘッダー、およびオリジンを許可しました( '*'値を使用)

Angular SPA

  • すべてのリクエストにwithCredentials = trueを設定するグローバルインターセプターを実装しました
  • 私のAPI呼び出しが http://abc.api.hydrogen.com/ ではなく//abc.api.hydrogen.com/を使用することを確認しました
  • また、インターセプターでX-XSRF-TOKENヘッダーを推奨されるように設定しようとしました here ですが、ブラウザーで設定されていないため、抽出されたトークンはnullです
2
cubiclewar

この問題は、ブラウザ/ angularがリクエストの送信元と同じドメインを持つリクエストにのみCookieを添付するために発生しました。

angular appがlocalhostで提供され、Laravel appがabc.api.hydrogen.localのようなドメインにある場合、開発環境でこれを修正するにはangularアプリからのリクエストをプロキシしました:

最初に、リクエストが相対ルートであることを確認します。たとえば、/ api/sanctum/crsfへの呼び出しを変更し、それが次にプロキシされます http://abc.api.hydrogen.local/sanctum/crsf

次に、プロジェクトのルートにプロキシ設定proxy.conf.jsonを作成します。

{
    "/api/*": {
      "target": "http://abc.api.hydrogen.local",
      "secure": false,
      "changeOrigin": true,
      "logLevel": "debug",
      "pathRewrite": {
        "^/api": ""
      }
    }
}

次に、angular.jsonを編集して、配信時にプロキシを使用します。

"architect": {
    ...
    "serve": {
        ...
        "options": {
            ....
            "proxyConfig": "proxy.conf.json"
        }
    }
}

最後に.envファイルに次の行を追加して、sanctumがリクエストをファーストパーティのSPAからのものであると識別し、ブラウザがCookieを読み取ってリクエストに添付できるようにします。

SANCTUM_STATEFUL_DOMAINS=localhost,.hydrogen.local
SESSION_DRIVER=cookie
SESSION_DOMAIN=localhost

これですべてが機能するはずです。

1
cubiclewar