Skip to content

Commit

Permalink
feat: add change password and TOTP secure logic
Browse files Browse the repository at this point in the history
  • Loading branch information
yanranxiaoxi committed Sep 5, 2022
1 parent 566e51f commit 8e0e93c
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 17 deletions.
31 changes: 21 additions & 10 deletions Class/GlobalHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,12 @@ public function curlGet($url, $post_array = [], $timeout = 10) {
public function isLogin() {
$visitor_ip = $this->getVisitorIP();
$visitor_infomation = ($visitor_ip === null) ? $_SERVER['HTTP_USER_AGENT'] : $visitor_ip;
$local_key = USERNAME . COOKIE_SECRET_KEY . 'opennav' . $visitor_infomation;
$local_key = USERNAME . PASSWORD . COOKIE_SECRET_KEY . 'opennav' . $visitor_infomation;
$local_key_hash = hash('sha256', $local_key);
// 获取 Session Cookie
$cookie_session_key = !empty($_COOKIE['opennav_session_key']) ? $_COOKIE['opennav_session_key'] : '';
// 如果已经成功登录
if ($cookie_session_key === $local_key_hash) {
// 延长 Cookie 时间为 30 天
if (ONLY_SECURE_CONNECTION === true) {
// 仅 HTTPS 设置 Session Cookie
setcookie('opennav_session_key', $local_key_hash, time() + 60 * 60 * 24 * 30, '/', null, true, true);
} else {
// 设置 Session Cookie
setcookie('opennav_session_key', $local_key_hash, time() + 60 * 60 * 24 * 30, '/', null, false, true);
}
return true;
} else {
return false;
Expand All @@ -107,7 +99,7 @@ public function isLogin() {
public function setLogin_AuthRequired() {
$visitor_ip = $this->getVisitorIP();
$visitor_infomation = ($visitor_ip === null) ? $_SERVER['HTTP_USER_AGENT'] : $visitor_ip;
$local_key = USERNAME . COOKIE_SECRET_KEY . 'opennav' . $visitor_infomation;
$local_key = USERNAME . PASSWORD . COOKIE_SECRET_KEY . 'opennav' . $visitor_infomation;
$local_key_hash = hash('sha256', $local_key);
if (ONLY_SECURE_CONNECTION === true) {
// 仅 HTTPS 设置 Session Cookie
Expand All @@ -118,6 +110,25 @@ public function setLogin_AuthRequired() {
}
}

/**
* 仅时基登录时设置短时登录状态「Auth Required」
*
* @return bool 设置状态
*/
public function setLoginByOnlyTimeBaseValidator_AuthRequired() {
$visitor_ip = $this->getVisitorIP();
$visitor_infomation = ($visitor_ip === null) ? $_SERVER['HTTP_USER_AGENT'] : $visitor_ip;
$local_key = USERNAME . PASSWORD . COOKIE_SECRET_KEY . 'opennav' . $visitor_infomation;
$local_key_hash = hash('sha256', $local_key);
if (ONLY_SECURE_CONNECTION === true) {
// 仅 HTTPS 设置 Session Cookie
return setcookie('opennav_session_key', $local_key_hash, time() + 60 * 30, '/', null, true, true);
} else {
// 设置 Session Cookie
return setcookie('opennav_session_key', $local_key_hash, time() + 60 * 30, '/', null, false, true);
}
}

/**
* 移除登录状态「Logic Safety」
*
Expand Down
6 changes: 4 additions & 2 deletions Controller/Login.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@
} elseif (LOGIN_AUTHENTICATION_MODE === 4) {
if (!empty($_POST['totp_code'])) {
if ($authenticator->verifyCode(TOTP_SECRET_KEY, $_POST['totp_code'])) {
$code = 200;
$message = 'success';
$code = 201;
$message = 'totp success';
} else {
$code = 403;
$message = 'TOTP Code 不正确!';
Expand All @@ -107,6 +107,8 @@
}
if ($code === 200) {
$helper->setLogin_AuthRequired();
} elseif ($code === 201) {
$helper->setLoginByOnlyTimeBaseValidator_AuthRequired();
}
$data = [
'code' => $code,
Expand Down
48 changes: 44 additions & 4 deletions Controller/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,57 @@
$error_message = '电子邮箱格式不正确!';
} elseif ($login_authentication_mode !== 3 && $login_authentication_mode !== 4 && $login_authentication_mode !== 5 && $login_authentication_mode !== 7) {
$error_message = '验证方式的组合不合法!';
} else {
$helper->setGlobalConfig_AuthRequired('USERNAME', USERNAME, $_POST['username']);
$helper->setGlobalConfig_AuthRequired('EMAIL', EMAIL, $email);
$helper->setGlobalConfig_AuthRequired('LOGIN_AUTHENTICATION_MODE', LOGIN_AUTHENTICATION_MODE, $login_authentication_mode);
}
$helper->setGlobalConfig_AuthRequired('USERNAME', USERNAME, $_POST['username']);
$helper->setGlobalConfig_AuthRequired('EMAIL', EMAIL, $email);
$helper->setGlobalConfig_AuthRequired('LOGIN_AUTHENTICATION_MODE', LOGIN_AUTHENTICATION_MODE, $login_authentication_mode);
} else {
$error_message = '设置失败!';
}
if (empty($error_message)) {
$data = [
'code' => 200,
'message' => '设置成功!'
'message' => 'success'
];
} else {
$data = [
'code' => 403,
'message' => $error_message
];
}
header('Content-Type: application/json; charset=utf-8');
exit(json_encode($data));
}


/**
* 进入密码设置流程
*/
if ($page === 'Password') {
require_once('../Template/Admin/User/Password.php');
}


/**
* 设置密码
*/
if ($page === 'SetPassword') {
$error_message = '';
if (!empty($_POST['password'])) {
$password_regex = '/^[0-9a-zA-Z!@#$%^&*()-_\[\]\{\}<>~`\+=,.;:\/?|]{6,128}$/';
if (!preg_match($password_regex, $_POST['password'])) {
$error_message = '密码格式不正确!';
} else {
$helper->setGlobalConfig_AuthRequired('PASSWORD', PASSWORD, password_hash($_POST['password'], PASSWORD_DEFAULT));
}
} else {
$error_message = '密码不能为空!';
}
if (empty($error_message)) {
$data = [
'code' => 200,
'message' => 'success'
];
} else {
$data = [
Expand Down
1 change: 1 addition & 0 deletions Template/Admin/Header.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<li class="layui-nav-item"><a href="./index.php?c=Admin&page=AddCategory"><i class="layui-icon layui-icon-add-circle-fine"></i> 添加分类</a></li>
<li class="layui-nav-item"><a href="./index.php?c=Admin&page=Links"><i class="layui-icon layui-icon-link"></i> 链接列表</a></li>
<li class="layui-nav-item"><a href="./index.php?c=Admin&page=AddLink"><i class="layui-icon layui-icon-add-circle-fine"></i> 添加链接</a></li>
<li class="layui-nav-item"><a href="./index.php?c=Login&page=Logout"><i class="layui-icon layui-icon-logout"></i> 退出登录</a></li>
</ul>
<ul class="layui-nav layui-layout-right">
<li class="layui-nav-item">
Expand Down
2 changes: 1 addition & 1 deletion Template/Admin/User/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

<div class="layui-form-item">
<button class="layui-btn" lay-submit lay-filter="set_options">保存设置</button>
<a class="layui-btn layui-btn-primary layui-border-green" target="_self" title="修改密码" href="#"><i class="fa fa-key"></i> 修改密码</a>
<a class="layui-btn layui-btn-primary layui-border-green" target="_self" title="修改密码" href="./index.php?c=User&page=Password"><i class="fa fa-key"></i> 修改密码</a>
<a class="layui-btn layui-btn-primary layui-border-green" target="_self" title="配置时基验证" href="./index.php?c=TimeBaseValidator&page=Setup"><i class="fa fa-clock-o"></i> 配置时基验证(TOTP)</a>
</div>

Expand Down
73 changes: 73 additions & 0 deletions Template/Admin/User/Password.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php require_once('../Template/Admin/Header.php'); ?>
<?php require_once('../Template/Admin/Left.php'); ?>

<div class="layui-body">
<!-- 内容主体区域 -->
<div class="layui-row content-body place-holder" style="padding-bottom: 3em;">
<!-- 说明提示框 -->
<div class="layui-col-lg12">
<div class="setting-msg">
<p>密码要求为 6-128 位字母、数字或特殊字符</p>
</div>
</div>
<!-- 说明提示框 END -->
<div class="layui-col-lg6">
<form class="layui-form layui-form-pane">

<div class="layui-form-item">
<label class="layui-form-label">新密码</label>
<div class="layui-input-block">
<input type="password" name="password" required lay-verify="required" autocomplete="off" placeholder="请输入新密码" class="layui-input" />
</div>
</div>

<div class="layui-form-item">
<label class="layui-form-label">确认新密码</label>
<div class="layui-input-block">
<input type="password" name="password2" required lay-verify="required" autocomplete="off" placeholder="请再次输入新密码" class="layui-input" />
</div>
</div>

<div class="layui-form-item">
<button class="layui-btn" lay-submit lay-filter="set_password">设置密码</button>
</div>

</form>
</div>
</div>
<!-- 内容主体区域 END -->
</div>

<?php require_once('../Template/Admin/Footer.php'); ?>

<script type="text/javascript">
layui.use(['form'], function() {
// 设置用户设置选项
layui.form.on('submit(set_password)', function(data) {
// 正则验证密码
const password_regex = /^[0-9a-zA-Z!@#$%^&*()-_\[\]\{\}<>~`\+=,.;:\/?|]{6,128}$/;
if (!password_regex.test(data.field.password)) {
layer.msg('密码需要 6-128 字母、数字或特殊字符!', {icon: 5});
return false;
}
if (data.field.password !== data.field.password2) {
layer.msg('两次输入的密码不一致!', {icon: 5});
return false;
}

$.post('./index.php?c=User&page=SetPassword', data.field, function(data, status) {
// 如果设置成功
if (data.code === 200) {
layer.msg('设置成功!请等待页面跳转 ...', {icon: 1});
setTimeout(() => {
window.location.href = './index.php?c=Login';
}, 500);
} else {
layer.msg(data.message, {icon: 5});
}
});
// console.log(data.field); // 当前容器的全部表单字段,名值对形式:{name: value}
return false; // 阻止表单跳转
});
})
</script>
4 changes: 4 additions & 0 deletions Template/Login.php
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@
// 如果验证成功
if (data.code === 200) {
window.location.href = './index.php?c=Admin';
} else if (data.code === 201) {
window.location.href = './';
} else {
layer.msg(data.message, {icon: 5});
}
Expand Down Expand Up @@ -398,6 +400,8 @@
// 如果验证成功
if (data.code === 200) {
window.location.href = './index.php?c=Admin';
} else if (data.code === 201) {
window.location.href = './';
} else {
layer.msg(data.message, {icon: 5});
}
Expand Down

0 comments on commit 8e0e93c

Please sign in to comment.