Skip to content
This repository has been archived by the owner on Nov 2, 2020. It is now read-only.

Commit

Permalink
feat(UserInfo): Add Cache Lock of user access_{time,ip} update
Browse files Browse the repository at this point in the history
  • Loading branch information
Rhilip committed Jul 16, 2019
1 parent f3e8e3f commit bb9b623
Showing 1 changed file with 18 additions and 10 deletions.
28 changes: 18 additions & 10 deletions apps/middleware/AuthByCookiesMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ public function handle($callable, \Closure $next)
app()->user->loadUserFromCookies();
$isAnonymousUser = app()->user->isAnonymous();

$now_ip = app()->request->getClientIp();
if ($controllerName === \apps\controllers\AuthController::class) {
if (!$isAnonymousUser && in_array($action, ['actionLogin', 'actionRegister','actionConfirm'])) {
if (!$isAnonymousUser && in_array($action, ['actionLogin', 'actionRegister', 'actionConfirm'])) {
return app()->response->redirect("/index");
} elseif ($action !== "actionLogout") {
if ($action == 'actionLogin') {
Expand All @@ -33,17 +34,17 @@ public function handle($callable, \Closure $next)
$query = app()->request->server('query_string');
$to = app()->request->server('path_info') . (strlen($query) > 0 ? '?' . $query : '');
app()->session->set('login_return_to', $to);
return app()->response->redirect("/auth/login");
return app()->response->redirect('/auth/login');
} else {
/**
* Check if session is locked with IP
*/
$userSessionId = app()->request->cookie(Constant::cookie_name);
if (substr($userSessionId, 0, 1) === '1') {
$record_ip_crc = substr($userSessionId, 2, 8);
$this_ip_crc = sprintf('%08x',crc32(app()->request->getClientIp()));
$this_ip_crc = sprintf('%08x', crc32($now_ip));

if (strcasecmp($record_ip_crc,$this_ip_crc) !== 0) { // The Ip isn't matched
if (strcasecmp($record_ip_crc, $this_ip_crc) !== 0) { // The Ip isn't matched
app()->cookie->delete(Constant::cookie_name);
return app()->response->redirect('/auth/login');
}
Expand All @@ -60,18 +61,25 @@ public function handle($callable, \Closure $next)
* /admin -> AdminController::actionIndex -> route.admin_index
* /admin/service -> AdminController::actionService -> route.admin_service
*/
$route = strtolower(str_replace(['apps\\controllers\\', 'Controller'], ['', ''], $controllerName)) .
"_" . strtolower(str_replace('action', '', $action));
$route = strtolower(str_replace(
['apps\\controllers\\', 'Controller', 'action'], '',
$controllerName . '_' . $action
)
);
$required_class = config('route.' . $route, false) ?: 1;
if (app()->user->getClass(true) < $required_class) {
return app()->response->setStatusCode(403);
}
}

// Update user status
app()->pdo->createCommand("UPDATE `users` SET last_access_at = NOW(), last_access_ip = INET6_ATON(:ip) WHERE id = :id;")->bindParams([
"ip" => app()->request->getClientIp(), "id" => app()->user->getId()
])->execute();
// We will not update user last_access_ip if it not change or expired
$last_access_ip = app()->redis->get('user:' . app()->user->getId() . ":access_ip");
if ($last_access_ip === false || $last_access_ip !== $now_ip) {
app()->pdo->createCommand("UPDATE `users` SET last_access_at = NOW(), last_access_ip = INET6_ATON(:ip) WHERE id = :id;")->bindParams([
"ip" => app()->request->getClientIp(), "id" => app()->user->getId()
])->execute();
app()->redis->set('user:' . app()->user->getId() . ":access_ip", $now_ip, 3600);
}

// 执行下一个中间件
return $next();
Expand Down

0 comments on commit bb9b623

Please sign in to comment.