如何使用分离的 vue 前端检索 Laravel CSRF 令牌 [英] How to retrieve laravel CSRF token using separated vue frontend

查看:30
本文介绍了如何使用分离的 vue 前端检索 Laravel CSRF 令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于 Laravel 后端和 Vue 前端彼此分开(在不同的目录和不同的子域中),有没有办法将 Laravel csrf 令牌传递给 Vue??

我正在构建一个应用程序,并希望将后端和前端分开以用于组织目的,因为它有利于团队合作.所以,它会是这样的:

  • api.mydomainexample.com(Laravel 后端)
  • mydomainexample.com(公共 Vue 前端)
  • admin.mydomainexample.com(仅适用于管理员的 Vue 前端)

这可能吗?我想可能是为前端项目运行一个 nodejs 服务器,并使 nodejs 服务器与 laravel 服务器通信.不知道该怎么做.

我发现了类似的stackoverflow问题,但他们的回答不解决我的问题.我发现的最好的东西是 this,建议使用 Laravel 护照.但是,提案是唯一有效的吗?如果是这样,Laravel 护照是否可以保护用户免受 CSRF 攻击?

实际上,如果有一种解决方法可以在保护 CSRF 令牌的同时实现后端和前端分离,那将是完美的!

解决方案

使用 Sanctum

LARAVEL 后端

  1. 通过 Composer 安装 Sanctum

    composer 需要 laravel/sanctum


  1. 发布 Sanctum 配置和迁移文件

    php artisan vendor:publish --provider=LaravelSanctumSanctumServiceProvider"


  1. 运行您的迁移 - Sanctum 将添加一个表来存储 API 令牌

    php artisan migrate


  1. 将 Sanctum 的中间件添加到 App/Http/Kernel.php 中的 api 中间件组


使用 LaravelSanctumHttpMiddlewareEnsureFrontendRequestsAreStateful;'api' =>[确保FrontendRequestsAreStateful::class,'油门:60,1',IlluminateRoutingMiddlewareSubstituteBindings::class,],

  1. 配置您的 SPA 将从哪些域发出请求.从文档:

<块引用>

您可以使用 sanctum 配置文件中的有状态配置选项来配置这些域.此配置设置确定哪些域将保持有状态"在向您的 API 发出请求时使用 Laravel 会话 cookie 进行身份验证.

所以 - 更新您的 configsanctum.php 以包含如下内容:

/*|--------------------------------------------------------------------------|有状态的域|--------------------------------------------------------------------------||来自以下域/主机的请求将接收有状态的 API|身份验证 cookie.通常,这些应包括您当地的|和通过前端 SPA 访问您的 API 的生产域.|*/'有状态' =>爆炸(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,localhost:8000,127.0.0.1,127.0.0.1:8000,::1')),


  1. 配置您的config/cors.php


['api/*', 'sanctum/csrf-cookie', '登录', '*'],'allowed_methods' =>['*'],'allowed_origins' =>['*'],'allowed_origins_patterns' =>[],'allowed_headers' =>['*'],'exposed_headers' =>[],'max_age' =>0,'supports_credentials' =>真的,];

  1. 配置您的config/session.php


/*|--------------------------------------------------------------------------|会话 Cookie 域|--------------------------------------------------------------------------||您可以在此处更改用于识别会话的 cookie 的域|在您的应用程序中.这将确定 cookie 是哪个域|在您的应用程序中可用.已经设置了一个合理的默认值.|*/'域' =>env('SESSION_DOMAIN', null),

  1. 在您的 .env 中,添加以下内容:


//将 .your-site.local 更改为您使用的任何域//请注意前导'.'SESSION_DOMAIN=.your-site.localSANCTUM_STATEFUL_DOMAINS=your-site.local:8000CORS_ALLOWED_ORIGINS=http://app.your-site.local:8000


  1. 运行 php artisan config:clear


VUE 前端

  1. 在您的前端,创建以下文件夹/文件结构@/src/services/api.js

api.js:

从'axios'导入axios;const apiClient = axios.create({baseURL: process.env.VUE_APP_API_URL,withCredentials: 真,});导出默认的 apiClient;

在根目录中,放置一个 .env 文件,其中包含以下内容:

VUE_APP_API_URL='http://api.your-site.local'

  1. 要进行身份验证,您的 SPA 应首先向 /sanctum/csrf-cookie 发出请求.这将设置 XSRF-TOKEN cookie.此令牌需要在后续请求中发送(axios 会自动为您处理).紧接着,您需要向 Laravel /login 路由发送一个 POST 请求.

在您的 Vue 前端登录组件上:


从'vue'导入Vue从 '../services/api' 导入 apiClient;导出默认{数据() {返回 {电子邮件:空,密码:空,加载:假,};},方法: {异步登录(){this.loading = true;//可以使用它来触发 :disabled on login buttonthis.errors = null;尝试 {等待 apiClient.get('/sanctum/csrf-cookie');等待 apiClient.post('/登录', {电子邮件:this.email,密码:this.password});//做一些了不起的事情} 捕捉(错误){this.errors = error.response &&error.response.data.errors;}this.loading = false;},},

Is there a way to pass Laravel csrf token to Vue given that the Laravel backend and the Vue frontend are separated from each other (in diferent directory and in diferent subdomains) ??

I'm building an application and would like to have separated backend and frontend for organization purposes and for because it facilitates team work. So, it would be something like:

  • api.mydomainexample.com (Laravel backend)
  • mydomainexample.com (Vue frontend for public)
  • admin.mydomainexample.com (Vue Frontend for admin only)

Is this possible? What I thought was maybe running a nodejs server for the frontend project and make the nodejs server communicate with the laravel server. Don't know how to do that.

I found similiar stackoverflow questions, but the responses from them do not solve my problem. The best thing I found was this, which proposes to use Laravel passport. But, is the proposal the only one that works? If so, does Laravel passport protect users from CSRF attacks?

Actually, if there is an workaround which enables to have separated backend and frontend while protecting against CSRF tokens, then that would be perfect!

解决方案

Use Sanctum

LARAVEL BACKEND

  1. Install Sanctum via Composer

    composer require laravel/sanctum


  1. Publish the Sanctum configuration and migration files

    php artisan vendor:publish --provider="LaravelSanctumSanctumServiceProvider"


  1. Run your migrations - Sanctum will add a table to store API tokens

    php artisan migrate


  1. Add Sanctum's middleware to your api middleware group in your App/Http/Kernel.php


use LaravelSanctumHttpMiddlewareEnsureFrontendRequestsAreStateful;

'api' => [
    EnsureFrontendRequestsAreStateful::class,
    'throttle:60,1',
    IlluminateRoutingMiddlewareSubstituteBindings::class,
],

  1. Configure which domains your SPA will be making requests from. From the docs:

You may configure these domains using the stateful configuration option in your sanctum configuration file. This configuration setting determines which domains will maintain "stateful" authentication using Laravel session cookies when making requests to your API.

So - Update your configsanctum.php to include something like this:

/*
    |--------------------------------------------------------------------------
    | Stateful Domains
    |--------------------------------------------------------------------------
    |
    | Requests from the following domains / hosts will receive stateful API
    | authentication cookies. Typically, these should include your local
    | and production domains which access your API via a frontend SPA.
    |
    */

    'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,localhost:8000,127.0.0.1,127.0.0.1:8000,::1')),


  1. Configure your config/cors.php


<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Cross-Origin Resource Sharing (CORS) Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your settings for cross-origin resource sharing
    | or "CORS". This determines what cross-origin operations may execute
    | in web browsers. You are free to adjust these settings as needed.
    |
    | To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
    |
    */

    'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', '*'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['*'],

    'allowed_origins_patterns' => [],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true,

];

  1. Configure your config/session.php


/*
    |--------------------------------------------------------------------------
    | Session Cookie Domain
    |--------------------------------------------------------------------------
    |
    | Here you may change the domain of the cookie used to identify a session
    | in your application. This will determine which domains the cookie is
    | available to in your application. A sensible default has been set.
    |
    */

    'domain' => env('SESSION_DOMAIN', null),

  1. In your .env, add the following:


// Change .your-site.local to whatever domain you are using
// Please note the leading '.'

SESSION_DOMAIN=.your-site.local 
SANCTUM_STATEFUL_DOMAINS=your-site.local:8000
CORS_ALLOWED_ORIGINS=http://app.your-site.local:8000


  1. Run a php artisan config:clear


VUE FRONTEND

  1. In your front-end, create the following folder/file structure @/src/services/api.js

api.js:

import axios from 'axios';

const apiClient = axios.create({
    baseURL: process.env.VUE_APP_API_URL,
    withCredentials: true,
});

export default apiClient;

In the root directory, place an .env file with the following in it:

VUE_APP_API_URL= 'http://api.your-site.local'  

  1. To authenticate, your SPA should first make a request to the /sanctum/csrf-cookie. This sets the XSRF-TOKEN cookie. This token needs to be sent on subsequent requests ( axios will handle this for you automatically ). Immediately after, you'll want to send a POST request to your Laravel /login route.

On your Vue front-end login component:


import Vue from 'vue'
import apiClient from '../services/api';

export default {
  data() {
    return {
        email: null,
        password: null,
        loading: false,
    };
  },
  methods: {

    async login() {
      this.loading = true; // can use this to triggle a :disabled on login button
      this.errors = null;

        try {
          await apiClient.get('/sanctum/csrf-cookie'); 
          await apiClient.post('/login', {
            email: this.email,
            password: this.password
          });

          // Do something amazing
          
        } catch (error) {
          this.errors = error.response && error.response.data.errors;
        }

      this.loading = false;
    },

  },

这篇关于如何使用分离的 vue 前端检索 Laravel CSRF 令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆