生成
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;
}
}