laravel csrf 生成 校验

生成
csrfToken是 开启startSession生成

生成40长度字符串

laravel\framework\src\illuminate\Foundation\Application.php #绑定的契约

中间件都会经过这个方法运行的
路径: laravel\framework\src\illuminate\Session\Middleware\StartSession.php 下的handel的方法 --初始的方法

   //初始session核心类
    protected function startSession(Request $request)
    {
        #通过$this->getSession($request) 对应契约绑定的容器  --\Illuminate\Contracts\Session\Session   解释出Store.php
        return tap($this->getSession($request), function ($session) use ($request) {
            $session->setRequestOnHandler($request);
            #\Illuminate\Session\Store::class  store在start中存在    store在illuminate\Session\Store.php
            $session->start(); //session初始化的定义
        });
    }

laravel\framework\src\illuminate\Session\Store.php 的setRequestOnHandler方法

    /**
     * Regenerate the CSRF token value.
     *
     * @return void
     */
    public function regenerateToken()
    {
        #随机生成40字符串,再用put存入进去
        $this->put('_token', Str::random(40));
    }
   /**
     * Start the session, reading the data from a handler.
     *
     * @return bool
     */
    public function start()
    {

        $this->loadSession(); //初始化session

        if (! $this->has('_token')) { //校验判断是否存在 csrf-token
            $this->regenerateToken();//第一次没有就是创建csrf
        }

        return $this->started = true;
    }
    /**
     * Set the request on the handler instance.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    //在处理程序实例上设置请求
    public function setRequestOnHandler($request)
    {
        if ($this->handlerNeedsRequest()) {
            $this->handler->setRequest($request);
        }
    }
}
    /**
     * Put a key / value pair or array of key / value pairs in the session.
     *
     * @param  string|array  $key
     * @param  mixed       $value
     * @return void
     */
    public function put($key, $value = null)
    {
        /*
         * $key = '_token'
         * $value = 'LZKM9tLoade2323jisdfkniofn3fNUKSGW'
         * $this = object[illuminate\Session\Store ]
         * */

        if (! is_array($key)) {
            $key = [$key => $value];
        }
        #csrf_toek 的生产的
        foreach ($key as $arrayKey => $arrayValue) {
            #其实就是一个赋值操作
            Arr::set($this->attributes, $arrayKey, $arrayValue);
            #$this->ddddd($this->attributes, $arrayKey, $arrayValue);
            #放到定义的属性中,在最后的拼接
            //$this->attributes[$arrayKey] = $arrayValue;
        }
        #dd(TestSession::all());
    }

    #&引用    $array就是$this->attributes   引用堆空间,耗费资源吗?是地址
    public function ddddd(&$array, $key, $value){
        //就是一个赋值
        $array[] = $value;
    }
    /**
     * Set an array item to a given value using "dot" notation.
     *
     * If no key is given to the method, the entire array will be replaced.
     *
     * @param  array   $array
     * @param  string  $key
     * @param  mixed   $value
     * @return array
     */
    public static function set(&$array, $key, $value)
    {
        if (is_null($key)) {
            return $array = $value;
        }

        $keys = explode('.', $key);

        while (count($keys) > 1) {
            $key = array_shift($keys);

            // If the key doesn't exist at this depth, we will just create an empty array
            // to hold the next value, allowing us to create the arrays to hold final
            // values at the correct depth. Then we'll keep digging into the array.
            if (! isset($array[$key]) || ! is_array($array[$key])) {
                $array[$key] = [];
            }

            $array = &$array[$key];
        }

        $array[array_shift($keys)] = $value;

        return $array;
    }

laravel\framework\src\illuminate\Support\Str.php 下的方法 random 生成字符串

    /**
     * Generate a more truly "random" alpha-numeric string.
     *
     * @param  int  $length
     * @return string
     */
    public static function random($length = 16)
    {
        $string = '';

        while (($len = strlen($string)) < $length) {
            $size = $length - $len;

            $bytes = random_bytes($size);

            $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
        }

        return $string;
    }

校验
VerifyCsrfToekn 是校验

#路径
E:\xampp\htdocs\xampp\laravel58\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     *
     * @throws \Illuminate\Session\TokenMismatchException
     */
    public function handle($request, Closure $next)
    {
        #是否开启单元测试runningUnitTests
        #白名单inExceptArray   盘查是否在这个白名单中有不用校验的路由
        #token 校验
        if (
            $this->isReading($request) ||
            $this->runningUnitTests() ||
            $this->inExceptArray($request) ||
            $this->tokensMatch($request)
        ) {
            return tap($next($request), function ($response) use ($request) {
                if ($this->shouldAddXsrfTokenCookie()) {
                    $this->addCookieToResponse($request, $response);
                }
            });
        }

        throw new TokenMismatchException;
    }
    /**
     * Get the CSRF token from the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return string
     */
    protected function getTokenFromRequest($request)
    {
        #请求 第一个from表单中是否有csrf,另一个是ajax请求头
        $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');

        if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
            #加密做饭
            $token = $this->encrypter->decrypt($header, static::serialized());
        }
        #返回token
        return $token;
    }
    /**
     * Determine if the session and input CSRF tokens match.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return bool
     */
    protected function tokensMatch($request)
    {
        #  @crsf
        $token = $this->getTokenFromRequest($request);

        #is_string校验 判断$request->session()->token() session中有没有token是不是字符串,is_string($token)是不是字符串,两者在校验
        return is_string($request->session()->token()) &&
               is_string($token) &&
               hash_equals($request->session()->token(), $token);
    }
    /**
     * Determine if the request has a URI that should pass through CSRF verification.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return bool
     */
    protected function inExceptArray($request)
    {
        foreach ($this->except as $except) {
            if ($except !== '/') {
                $except = trim($except, '/');
            }
            #fullUrlIs--路由url存在   都存在返回true
            if ($request->fullUrlIs($except) || $request->is($except)) {
                return true;
            }
        }

        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟伟哦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值