Laravel 前后端分离 csrf 防护 您所在的位置:网站首页 Django前后分离crsf Laravel 前后端分离 csrf 防护

Laravel 前后端分离 csrf 防护

2024-03-28 20:17| 来源: 网络整理| 查看: 265

首先根据文档详解csrf的流程机制,然后分析下怎么在前后端分离的情况下进行csrf防护? 1.首先介绍token的生成,在 Illuminate\Session\Store.php 中start() 方法中,然后点击方法regenerateToken()方法中:

public function start() { $this->loadSession(); if (! $this->has('_token')) { $this->regenerateToken(); } return $this->started = true; } public function regenerateToken() { $this->put('_token', Str::random(40)); }

可见token是每次加载session时自动存入进session中。 2.然后看前台获取token值,首先表单中 {{csrf_token()}} 点入进去可以看到

function csrf_field() { return new HtmlString(''); //点入进去csrf_token方法中 } function csrf_token() { $session = app('session'); if (isset($session)) { return $session->token(); } throw new RuntimeException('Application session store not set.'); }

可以看到前台token值是从session存储的token值中获取到的。 3.然后看中间件是怎么验证前台提交的_token值: 在VerifyCsrfToken.php中继承Middleware类,点击进入类中查看handle方法

public function handle($request, Closure $next) { if ( $this->isReading($request) || //验证请求方式,如果不在数组['HEAD', 'GET', 'OPTIONS']中 返回false; $this->runningUnitTests() || //查看程序是否在进行测试 正式运行返回false; $this->inExceptArray($request) || //查看$except(白名单,不用验证_token)数组,如果请求路径在数组中返回true; $this->tokensMatch($request) //进行token验证 ) { return $this->addCookieToResponse($request, $next($request)); } throw new TokenMismatchException; }

我们点击$this->tokensMatch()方法中可以看到请求中的token和session中的token是否相等:

protected function tokensMatch($request) { $token = $this->getTokenFromRequest($request); //从请求中获取_token值 return is_string($request->session()->token()) && is_string($token) && hash_equals($request->session()->token(), $token); //session中的token和请求中的token是否相等; }

点击进入$this->getTokenFromRequest() 方法中

protected function getTokenFromRequest($request) { $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN'); if (! $token && $header = $request->header('X-XSRF-TOKEN')) { $token = $this->encrypter->decrypt($header); } return $token; }

从中可以看到获取请求中token值的几种方法: from表单、头部值X-CSRF-TOKEN、头部值X-XSRF-TOKEN 这几种方试,只要明白了中间件怎么接收token值进行判断,然后前台就那么几种传值方式了 第一种 form表单传值 {{ csrf_field() }}或ajaxpost携带值 对应 $request->input('_token') 第二种 header头传值:

$.ajaxSetup({ //修改jquery库中代码 headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });

如果你用vue,只需将 resources/assets/js/bootstrap.js 引入你的文件中 然后 meta标签头部值放入总模板里,每次axios请求都会携带X-CSRF-TOKEN进入中间件进行验证,下面为js文件:

let token = document.head.querySelector('meta[name="csrf-token"]'); if (token) { window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content; } else { console.error('CSRF token not found: https://learnku.com/docs/laravel/csrf#csrf-x-csrf-token'); }

至此 从token值生成到前端携带token到后台验证已经完全走完一个流程了,接下来想一下假如前后端分离情况下怎么进行token验证 很简单每次提交前用api的形式获取token值传入前端(csrf_token()获取token值),然后前端用header头形式或ajax形式传入过来就可以了。 如果感觉有用就赞一下呗!!!

本作品采用《CC 协议》,转载必须注明作者和本文链接 自由飞


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有