chaoyu/app/middleware/Csrf.php

79 lines
2.5 KiB
PHP
Executable File

<?php
namespace app\middleware;
use Closure;
/**
* CSRF校验
*/
class Csrf
{
public function handle($request, Closure $next)
{
$csrfToken = session('_token');
if (empty($csrfToken)) {
$csrfToken = randomStr(1, 32);
session('_token', $csrfToken);
}
$paramToken = input('param._token', '');
if (!empty($paramToken)) {
if ($paramToken != $csrfToken) {
return $this->csrfError($request);
}
} elseif($request->isPost() || $request->isAjax()) {
if (empty($paramToken) || $paramToken != $csrfToken) {
return $this->csrfError($request);
}
//HTTP_REFERER 认证
$referer = $_SERVER['HTTP_REFERER'] ?? null;
if(!empty($referer)) {
$domain = $request->domain();
$urlInfo = parse_url($referer);
$scheme = $urlInfo['scheme'] ?? '';
$requestSrc = '';
if (!empty($scheme)) {
$requestSrc = $scheme.'://'.($urlInfo['host'] ?? '');
}
if($domain != $requestSrc) {
return $this->csrfError($request);
}
}
}
$request->csrfToken = $csrfToken;
return $next($request);
}
protected function csrfError($request, $msg = '非法请求, 用户身份认证失败!')
{
if($request->isAjax()) {
return json(['code'=>401, 'msg'=>$msg],200);
} else {
$referer = $_SERVER['HTTP_REFERER'] ?? null;
if (empty($referer)) {
$url = '/';
} else {
$domain = $request->domain();
$urlInfo = parse_url($referer);
$scheme = $urlInfo['scheme'] ?? '';
$requestSrc = '';
if (!empty($scheme)) {
$requestSrc = $scheme.'://'.($urlInfo['host'] ?? '');
}
if($domain != $requestSrc) {
$url = '/';
} else {
$url = 'javascript:history.back(-1);';
}
}
$errorData = [
'code'=> 401,
'msg' => $msg,
'data' => [],
'wait' => 5,
'url' => $url
];
return view('error/400', $errorData);
// 返回401视图 response type has html、json、jsonp、xml、file、view、redirect
}
}
}