mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-30 22:24:55 +08:00
优化异常和错误
This commit is contained in:
parent
d1c9dfa46f
commit
ab73ac4055
8
app/Exceptions/ServiceUnavailable.php
Normal file
8
app/Exceptions/ServiceUnavailable.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exceptions;
|
||||||
|
|
||||||
|
class ServiceUnavailable extends \Exception
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -22,15 +22,12 @@ class Controller extends \Phalcon\Mvc\Controller
|
|||||||
public function beforeExecuteRoute(Dispatcher $dispatcher)
|
public function beforeExecuteRoute(Dispatcher $dispatcher)
|
||||||
{
|
{
|
||||||
if ($this->isNotSafeRequest()) {
|
if ($this->isNotSafeRequest()) {
|
||||||
if (!$this->checkHttpReferer() || !$this->checkCsrfToken()) {
|
$this->checkHttpReferer();
|
||||||
$dispatcher->forward([
|
$this->checkCsrfToken();
|
||||||
'controller' => 'public',
|
|
||||||
'action' => 'robot',
|
|
||||||
]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->checkRateLimit();
|
||||||
|
|
||||||
$this->authUser = $this->getAuthUser();
|
$this->authUser = $this->getAuthUser();
|
||||||
|
|
||||||
if (!$this->authUser) {
|
if (!$this->authUser) {
|
||||||
|
@ -26,18 +26,6 @@ class PublicController extends \Phalcon\Mvc\Controller
|
|||||||
$this->response->redirect(['for' => 'admin.login']);
|
$this->response->redirect(['for' => 'admin.login']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/robot", name="admin.robot")
|
|
||||||
*/
|
|
||||||
public function robotAction()
|
|
||||||
{
|
|
||||||
$isAjaxRequest = is_ajax_request();
|
|
||||||
|
|
||||||
if ($isAjaxRequest) {
|
|
||||||
return $this->jsonError(['msg' => '疑似机器人请求']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/forbidden", name="admin.forbidden")
|
* @Route("/forbidden", name="admin.forbidden")
|
||||||
*/
|
*/
|
||||||
|
@ -13,8 +13,7 @@ use App\Traits\Security as SecurityTrait;
|
|||||||
class SessionController extends \Phalcon\Mvc\Controller
|
class SessionController extends \Phalcon\Mvc\Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
use ResponseTrait;
|
use ResponseTrait, SecurityTrait;
|
||||||
use SecurityTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/login", name="admin.login")
|
* @Route("/login", name="admin.login")
|
||||||
@ -23,13 +22,8 @@ class SessionController extends \Phalcon\Mvc\Controller
|
|||||||
{
|
{
|
||||||
if ($this->request->isPost()) {
|
if ($this->request->isPost()) {
|
||||||
|
|
||||||
if (!$this->checkHttpReferer() || !$this->checkCsrfToken()) {
|
$this->checkHttpReferer();
|
||||||
$this->dispatcher->forward([
|
$this->checkCsrfToken();
|
||||||
'controller' => 'public',
|
|
||||||
'action' => 'robot',
|
|
||||||
]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$sessionService = new SessionService();
|
$sessionService = new SessionService();
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{ item.title }}</td>
|
<td>{{ item.title }}</td>
|
||||||
<td><span class="layui-badge layui-bg-gray">{{ item.lesson_count }}</span></td>
|
<td><span class="layui-badge layui-bg-gray">{{ item.lesson_count }}</span></td>
|
||||||
<td>{{ expiry_info(item.expiry) }}</td>
|
<td>{{ study_expiry_info(item.study_expiry) }}</td>
|
||||||
<td>
|
<td>
|
||||||
<p>市场价:¥{{ item.market_price }}</p>
|
<p>市场价:¥{{ item.market_price }}</p>
|
||||||
<p>会员价:¥{{ item.vip_price }}</p>
|
<p>会员价:¥{{ item.vip_price }}</p>
|
||||||
|
@ -13,13 +13,7 @@ class Controller extends \Phalcon\Mvc\Controller
|
|||||||
|
|
||||||
public function beforeExecuteRoute(Dispatcher $dispatcher)
|
public function beforeExecuteRoute(Dispatcher $dispatcher)
|
||||||
{
|
{
|
||||||
if (!$this->checkRateLimit()) {
|
$this->checkRateLimit();
|
||||||
$dispatcher->forward([
|
|
||||||
'controller' => 'public',
|
|
||||||
'action' => 'throttle',
|
|
||||||
]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,4 @@ class PublicController extends \Phalcon\Mvc\Controller
|
|||||||
|
|
||||||
use ResponseTrait;
|
use ResponseTrait;
|
||||||
|
|
||||||
/**
|
|
||||||
* @Get("/throttle", name="api.throttle")
|
|
||||||
*/
|
|
||||||
public function throttleAction()
|
|
||||||
{
|
|
||||||
return $this->jsonError(['msg' => '请求过于频繁']);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,7 @@ class Controller extends \Phalcon\Mvc\Controller
|
|||||||
|
|
||||||
public function beforeExecuteRoute(Dispatcher $dispatcher)
|
public function beforeExecuteRoute(Dispatcher $dispatcher)
|
||||||
{
|
{
|
||||||
if (!$this->checkRateLimit()) {
|
$this->checkRateLimit();
|
||||||
$dispatcher->forward([
|
|
||||||
'controller' => 'public',
|
|
||||||
'action' => 'throttle',
|
|
||||||
]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,4 @@ class PublicController extends \Phalcon\Mvc\Controller
|
|||||||
|
|
||||||
use ResponseTrait;
|
use ResponseTrait;
|
||||||
|
|
||||||
/**
|
|
||||||
* @Get("/throttle", name="html5.throttle")
|
|
||||||
*/
|
|
||||||
public function throttleAction()
|
|
||||||
{
|
|
||||||
return $this->jsonError(['msg' => '请求过于频繁']);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -20,23 +20,12 @@ class Controller extends \Phalcon\Mvc\Controller
|
|||||||
|
|
||||||
public function beforeExecuteRoute(Dispatcher $dispatcher)
|
public function beforeExecuteRoute(Dispatcher $dispatcher)
|
||||||
{
|
{
|
||||||
if (!$this->checkRateLimit()) {
|
if ($this->isNotSafeRequest()) {
|
||||||
$dispatcher->forward([
|
$this->checkHttpReferer();
|
||||||
'controller' => 'public',
|
$this->checkCsrfToken();
|
||||||
'action' => 'throttle',
|
|
||||||
]);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->isNotSafeRequest()) {
|
$this->checkRateLimit();
|
||||||
if (!$this->checkHttpReferer() || !$this->checkCsrfToken()) {
|
|
||||||
$dispatcher->forward([
|
|
||||||
'controller' => 'public',
|
|
||||||
'action' => 'robot',
|
|
||||||
]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->siteSettings = $this->getSiteSettings();
|
$this->siteSettings = $this->getSiteSettings();
|
||||||
$this->navList = $this->getNavList();
|
$this->navList = $this->getNavList();
|
||||||
|
@ -53,7 +53,7 @@ class ErrorController extends \Phalcon\Mvc\Controller
|
|||||||
$isAjaxRequest = is_ajax_request();
|
$isAjaxRequest = is_ajax_request();
|
||||||
|
|
||||||
if ($isAjaxRequest || $isApiRequest) {
|
if ($isAjaxRequest || $isApiRequest) {
|
||||||
return $this->jsonError(['code' => 'sys.uri_not_found']);
|
return $this->jsonError(['code' => 'sys.not_found']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,4 +65,12 @@ class ErrorController extends \Phalcon\Mvc\Controller
|
|||||||
$this->response->setStatusCode(500);
|
$this->response->setStatusCode(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Get("/503", name="web.error.503")
|
||||||
|
*/
|
||||||
|
public function show503Action()
|
||||||
|
{
|
||||||
|
$this->response->setStatusCode(503);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,56 +12,6 @@ class PublicController extends \Phalcon\Mvc\Controller
|
|||||||
|
|
||||||
use ResponseTrait;
|
use ResponseTrait;
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/auth", name="web.auth")
|
|
||||||
*/
|
|
||||||
public function authAction()
|
|
||||||
{
|
|
||||||
$isAjaxRequest = is_ajax_request();
|
|
||||||
|
|
||||||
if ($isAjaxRequest) {
|
|
||||||
return $this->jsonError(['msg' => '会话已过期,请重新登录']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->response->redirect(['for' => 'web.login']);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/robot", name="web.robot")
|
|
||||||
*/
|
|
||||||
public function robotAction()
|
|
||||||
{
|
|
||||||
$isAjaxRequest = is_ajax_request();
|
|
||||||
|
|
||||||
if ($isAjaxRequest) {
|
|
||||||
return $this->jsonError(['msg' => '疑似机器人请求']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Route("/forbidden", name="web.forbidden")
|
|
||||||
*/
|
|
||||||
public function forbiddenAction()
|
|
||||||
{
|
|
||||||
$isAjaxRequest = is_ajax_request();
|
|
||||||
|
|
||||||
if ($isAjaxRequest) {
|
|
||||||
return $this->jsonError(['msg' => '无相关操作权限']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Get("/throttle", name="web.throttle")
|
|
||||||
*/
|
|
||||||
public function throttleAction()
|
|
||||||
{
|
|
||||||
$isAjaxRequest = is_ajax_request();
|
|
||||||
|
|
||||||
if ($isAjaxRequest) {
|
|
||||||
return $this->jsonError(['msg' => 'web请求过于频繁']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Get("/content/img/{id:[0-9]+}", name="web.content.img")
|
* @Get("/content/img/{id:[0-9]+}", name="web.content.img")
|
||||||
*/
|
*/
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Traits;
|
namespace App\Traits;
|
||||||
|
|
||||||
use App\Services\Throttle;
|
use App\Validators\Security as SecurityValidator;
|
||||||
use Phalcon\Di;
|
use Phalcon\Di;
|
||||||
use Phalcon\Http\Request;
|
use Phalcon\Http\Request;
|
||||||
|
|
||||||
@ -11,39 +11,23 @@ trait Security
|
|||||||
|
|
||||||
public function checkCsrfToken()
|
public function checkCsrfToken()
|
||||||
{
|
{
|
||||||
/**
|
$validator = new SecurityValidator();
|
||||||
* @var Request $request
|
|
||||||
*/
|
|
||||||
$request = Di::getDefault()->get('request');
|
|
||||||
|
|
||||||
$tokenKey = $request->getHeader('X-Csrf-Token-Key');
|
$validator->checkCsrfToken();
|
||||||
$tokenValue = $request->getHeader('X-Csrf-Token-Value');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var \App\Library\Security $security
|
|
||||||
*/
|
|
||||||
$security = Di::getDefault()->get('security');
|
|
||||||
|
|
||||||
return $security->checkToken($tokenKey, $tokenValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkHttpReferer()
|
public function checkHttpReferer()
|
||||||
{
|
{
|
||||||
/**
|
$validator = new SecurityValidator();
|
||||||
* @var Request $request
|
|
||||||
*/
|
|
||||||
$request = Di::getDefault()->get('request');
|
|
||||||
|
|
||||||
$httpHost = parse_url($request->getHttpReferer(), PHP_URL_HOST);
|
$validator->checkHttpReferer();
|
||||||
|
|
||||||
return $httpHost == $request->getHttpHost();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkRateLimit()
|
public function checkRateLimit()
|
||||||
{
|
{
|
||||||
$throttle = new Throttle();
|
$validator = new SecurityValidator();
|
||||||
|
|
||||||
return $throttle->checkRateLimit();
|
$validator->checkRateLimit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isNotSafeRequest()
|
public function isNotSafeRequest()
|
||||||
|
@ -123,7 +123,7 @@ class Account extends Validator
|
|||||||
$user = $this->checkUserLogin($name, $password);
|
$user = $this->checkUserLogin($name, $password);
|
||||||
|
|
||||||
if ($user->admin_role == 0) {
|
if ($user->admin_role == 0) {
|
||||||
throw new ForbiddenException('sys.access_denied');
|
throw new ForbiddenException('sys.forbidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $user;
|
return $user;
|
||||||
|
@ -3,13 +3,49 @@
|
|||||||
namespace App\Validators;
|
namespace App\Validators;
|
||||||
|
|
||||||
use App\Exceptions\BadRequest as BadRequestException;
|
use App\Exceptions\BadRequest as BadRequestException;
|
||||||
|
use App\Exceptions\ServiceUnavailable as ServiceUnavailableException;
|
||||||
use App\Library\Validator\Common as CommonValidator;
|
use App\Library\Validator\Common as CommonValidator;
|
||||||
use App\Services\Captcha as CaptchaService;
|
use App\Services\Captcha as CaptchaService;
|
||||||
|
use App\Services\Throttle as ThrottleService;
|
||||||
use App\Services\VerifyCode as VerifyCodeService;
|
use App\Services\VerifyCode as VerifyCodeService;
|
||||||
|
|
||||||
class Security extends Validator
|
class Security extends Validator
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public function checkCsrfToken()
|
||||||
|
{
|
||||||
|
$tokenKey = $this->request->getHeader('X-Csrf-Token-Key');
|
||||||
|
$tokenValue = $this->request->getHeader('X-Csrf-Token-Value');
|
||||||
|
|
||||||
|
$result = $this->security->checkToken($tokenKey, $tokenValue);
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
throw new BadRequestException('security.invalid_csrf_token');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkHttpReferer()
|
||||||
|
{
|
||||||
|
$httpHost = parse_url($this->request->getHttpReferer(), PHP_URL_HOST);
|
||||||
|
|
||||||
|
$result = $httpHost == $this->request->getHttpHost();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
throw new BadRequestException('security.invalid_http_referer');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkRateLimit()
|
||||||
|
{
|
||||||
|
$throttleService = new ThrottleService();
|
||||||
|
|
||||||
|
$result = $throttleService->checkRateLimit();
|
||||||
|
|
||||||
|
if (!$result) {
|
||||||
|
throw new ServiceUnavailableException('security.too_many_requests');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function checkVerifyCode($key, $code)
|
public function checkVerifyCode($key, $code)
|
||||||
{
|
{
|
||||||
$verifyCodeService = new VerifyCodeService();
|
$verifyCodeService = new VerifyCodeService();
|
||||||
|
@ -12,14 +12,14 @@ class Validator extends Component
|
|||||||
public function checkAuthUser($authUser)
|
public function checkAuthUser($authUser)
|
||||||
{
|
{
|
||||||
if (empty($authUser['id'])) {
|
if (empty($authUser['id'])) {
|
||||||
throw new UnauthorizedException('sys.auth_failed');
|
throw new UnauthorizedException('sys.unauthorized');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function checkOwner($userId, $ownerId)
|
public function checkOwner($userId, $ownerId)
|
||||||
{
|
{
|
||||||
if ($userId != $ownerId) {
|
if ($userId != $ownerId) {
|
||||||
throw new ForbiddenException('sys.access_denied');
|
throw new ForbiddenException('sys.forbidden');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ namespace Bootstrap;
|
|||||||
use App\Exceptions\BadRequest as BadRequestException;
|
use App\Exceptions\BadRequest as BadRequestException;
|
||||||
use App\Exceptions\Forbidden as ForbiddenException;
|
use App\Exceptions\Forbidden as ForbiddenException;
|
||||||
use App\Exceptions\NotFound as NotFoundException;
|
use App\Exceptions\NotFound as NotFoundException;
|
||||||
|
use App\Exceptions\ServiceUnavailable as ServiceUnavailableException;
|
||||||
use App\Exceptions\Unauthorized as UnauthorizedException;
|
use App\Exceptions\Unauthorized as UnauthorizedException;
|
||||||
use App\Library\Logger as AppLogger;
|
use App\Library\Logger as AppLogger;
|
||||||
use Phalcon\Mvc\User\Component;
|
use Phalcon\Mvc\User\Component;
|
||||||
@ -60,6 +61,8 @@ class HttpErrorHandler extends Component
|
|||||||
$this->response->setStatusCode(403);
|
$this->response->setStatusCode(403);
|
||||||
} elseif ($e instanceof NotFoundException) {
|
} elseif ($e instanceof NotFoundException) {
|
||||||
$this->response->setStatusCode(404);
|
$this->response->setStatusCode(404);
|
||||||
|
} elseif ($e instanceof ServiceUnavailableException) {
|
||||||
|
$this->response->setStatusCode(503);
|
||||||
} else {
|
} else {
|
||||||
$this->response->setStatusCode(500);
|
$this->response->setStatusCode(500);
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,22 @@
|
|||||||
$error = [];
|
$error = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通用相关
|
* 系统相关
|
||||||
*/
|
*/
|
||||||
$error['sys.uri_not_found'] = '资源地址不存在';
|
$error['sys.unauthorized'] = '认证失败';
|
||||||
$error['sys.invalid_referer'] = '非法的请求来源';
|
$error['sys.forbidden'] = '拒绝访问';
|
||||||
$error['sys.auth_failed'] = '认证失败';
|
$error['sys.bad_request'] = '无效的请求';
|
||||||
$error['sys.access_denied'] = '拒绝访问';
|
$error['sys.not_found'] = '资源不存在';
|
||||||
|
$error['sys.internal_server_error'] = '内部错误';
|
||||||
|
$error['sys.service_unavailable'] = '服务不可用';
|
||||||
$error['sys.unknown_error'] = '未知错误';
|
$error['sys.unknown_error'] = '未知错误';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 安全相关
|
* 安全相关
|
||||||
*/
|
*/
|
||||||
|
$error['security.too_many_requests'] = '请求过于频繁';
|
||||||
|
$error['security.invalid_csrf_token'] = '无效的CSRF令牌';
|
||||||
|
$error['security.invalid_http_referer'] = '无效请求来源';
|
||||||
$error['security.invalid_captcha_code'] = '无效的验证码';
|
$error['security.invalid_captcha_code'] = '无效的验证码';
|
||||||
$error['security.invalid_verify_code'] = '无效的验证码';
|
$error['security.invalid_verify_code'] = '无效的验证码';
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user