feat: improve security

This commit is contained in:
Baoshuo Ren 2023-02-13 15:45:06 +08:00
parent 14a2ab6f20
commit 8314eb6760
Signed by: baoshuo
GPG Key ID: 00CB9680AB29F51A
4 changed files with 40 additions and 2 deletions

View File

@ -36,6 +36,7 @@ function resetPassword() {
"update user_info", "update user_info",
"set", [ "set", [
"password" => $newPW, "password" => $newPW,
"remember_token" => '',
"extra" => DB::json_remove('extra', '$.reset_password_check_code', '$.reset_password_time'), "extra" => DB::json_remove('extra', '$.reset_password_check_code', '$.reset_password_time'),
], ],
"where", [ "where", [

View File

@ -559,6 +559,7 @@ if ($cur_tab == 'index') {
"update user_info", "update user_info",
"set", [ "set", [
"password" => getPasswordToStore($password, $vdata['username']), "password" => getPasswordToStore($password, $vdata['username']),
"remember_token" => '',
], ],
"where", [ "where", [
"username" => $vdata['username'], "username" => $vdata['username'],

View File

@ -390,12 +390,13 @@ EOD);
DB::update([ DB::update([
"update user_info", "update user_info",
"set", [ "set", [
'password' => getPasswordToStore($new_password, $user['username']), "password" => getPasswordToStore($new_password, $user['username']),
"remember_token" => "",
], ],
"where", ["username" => $user['username']] "where", ["username" => $user['username']]
]); ]);
dieWithJsonData(['status' => 'success', 'message' => '密码修改成功']); dieWithAlert('密码修改成功!');
} }
} elseif ($cur_tab == 'privilege') { } elseif ($cur_tab == 'privilege') {
$users_default_permissions = UOJContext::getMeta('users_default_permissions'); $users_default_permissions = UOJContext::getMeta('users_default_permissions');

View File

@ -3,31 +3,43 @@
class Auth { class Auth {
public static function check() { public static function check() {
global $myUser; global $myUser;
return $myUser !== null; return $myUser !== null;
} }
public static function id() { public static function id() {
global $myUser; global $myUser;
if ($myUser === null) { if ($myUser === null) {
return null; return null;
} }
return $myUser['username']; return $myUser['username'];
} }
public static function user() { public static function user() {
global $myUser; global $myUser;
return $myUser; return $myUser;
} }
public static function property($name) { public static function property($name) {
global $myUser; global $myUser;
if (!$myUser) { if (!$myUser) {
return false; return false;
} }
return $myUser[$name]; return $myUser[$name];
} }
public static function login($username, $remember = true) { public static function login($username, $remember = true) {
if (!validateUsername($username)) { if (!validateUsername($username)) {
return; return;
} }
$_SESSION['username'] = $username; $_SESSION['username'] = $username;
if ($remember) { if ($remember) {
$remember_token = DB::selectSingle([ $remember_token = DB::selectSingle([
"select remember_token from user_info", "select remember_token from user_info",
@ -44,6 +56,8 @@ class Auth {
} }
$_SESSION['last_login'] = time(); $_SESSION['last_login'] = time();
$_SESSION['remember_token'] = $remember_token;
$expire = time() + 60 * 60 * 24 * 7; $expire = time() + 60 * 60 * 24 * 7;
Cookie::safeSet('uoj_username', $username, $expire, '/', array('httponly' => true)); Cookie::safeSet('uoj_username', $username, $expire, '/', array('httponly' => true));
Cookie::safeSet('uoj_remember_token', $remember_token, $expire, '/', array('httponly' => true)); Cookie::safeSet('uoj_remember_token', $remember_token, $expire, '/', array('httponly' => true));
@ -54,13 +68,17 @@ class Auth {
"set", ["last_login_time" => UOJTime::$time_now_str], "set", ["last_login_time" => UOJTime::$time_now_str],
"where", ["username" => $username] "where", ["username" => $username]
]); ]);
session_regenerate_id(true);
} }
public static function logout() { public static function logout() {
session_unset(); session_unset();
Cookie::safeUnset(session_name(), '/'); Cookie::safeUnset(session_name(), '/');
Cookie::safeUnset('uoj_username', '/'); Cookie::safeUnset('uoj_username', '/');
Cookie::safeUnset('uoj_remember_token', '/'); Cookie::safeUnset('uoj_remember_token', '/');
DB::update([ DB::update([
"update user_info", "update user_info",
"set", ["remember_token" => ''], "set", ["remember_token" => ''],
@ -79,25 +97,39 @@ class Auth {
if (!validateUsername($_SESSION['username'])) { if (!validateUsername($_SESSION['username'])) {
return; return;
} }
$myUser = UOJUser::query($_SESSION['username']); $myUser = UOJUser::query($_SESSION['username']);
// 当 remember_token 不同时,注销登录
if ($_SESSION['remember_token'] !== $myUser['remember_token']) {
$myUser = null;
return;
}
return; return;
} }
$remember_token = Cookie::safeGet('uoj_remember_token', '/'); $remember_token = Cookie::safeGet('uoj_remember_token', '/');
if ($remember_token != null) { if ($remember_token != null) {
$username = Cookie::safeGet('uoj_username', '/'); $username = Cookie::safeGet('uoj_username', '/');
if (!validateUsername($username)) { if (!validateUsername($username)) {
return; return;
} }
$myUser = UOJUser::query($username); $myUser = UOJUser::query($username);
if ($myUser['remember_token'] !== $remember_token) { if ($myUser['remember_token'] !== $remember_token) {
$myUser = null; $myUser = null;
return; return;
} }
$_SESSION['username'] = $myUser['username']; $_SESSION['username'] = $myUser['username'];
return; return;
} }
} }
public static function init() { public static function init() {
global $myUser; global $myUser;
@ -105,15 +137,18 @@ class Auth {
if ($myUser && UOJUser::getAccountStatus($myUser) != 'ok') { if ($myUser && UOJUser::getAccountStatus($myUser) != 'ok') {
$myUser = null; $myUser = null;
} }
if ($myUser) { if ($myUser) {
if (!isset($_SESSION['last_login'])) { if (!isset($_SESSION['last_login'])) {
$_SESSION['last_login'] = strtotime($myUser['last_login_time']); $_SESSION['last_login'] = strtotime($myUser['last_login_time']);
} }
$myUser = UOJUser::updateVisitHistory($myUser, [ $myUser = UOJUser::updateVisitHistory($myUser, [
'remote_addr' => UOJContext::remoteAddr(), 'remote_addr' => UOJContext::remoteAddr(),
'http_x_forwarded_for' => UOJContext::httpXForwardedFor(), 'http_x_forwarded_for' => UOJContext::httpXForwardedFor(),
'http_user_agent' => UOJContext::httpUserAgent() 'http_user_agent' => UOJContext::httpUserAgent()
]); ]);
$_SESSION['last_visited'] = time(); $_SESSION['last_visited'] = time();
} }
} }