优化登录逻辑。

This commit is contained in:
2026-08-12 10:57:37 +08:00
parent a1d57d6b44
commit 043bf8773b
5 changed files with 52 additions and 44 deletions
+9 -13
View File
@@ -4,23 +4,21 @@ const API_BASE = '/api';
// 当前登录用户
let currentUser = null;
// 跳转到独立登录页
// 跳转到登录页
function goLogin() {
localStorage.removeItem('token');
localStorage.removeItem('user');
localStorage.removeItem('menus');
currentUser = null;
location.replace('/admin/login');
}
// 页面初始化(登录已移至独立页面 /admin/login,菜单与页面框架由服务端模板按权限渲染)
// 认证完全依赖 HttpOnly Cookie,不再使用 localStorage 存储 token
document.addEventListener('DOMContentLoaded', () => {
const token = localStorage.getItem('token');
if (!token) {
// 从服务端注入的用户信息初始化
currentUser = window.__currentUser || null;
if (!currentUser) {
goLogin();
return;
}
currentUser = JSON.parse(localStorage.getItem('user') || '{}');
const usernameEl = document.getElementById('username');
if (usernameEl) {
usernameEl.textContent = currentUser.nickname || currentUser.username;
@@ -97,12 +95,11 @@ async function refreshCurrentUser() {
const fresh = data.data || {};
// 角色发生变化时重新加载页面,让服务端按新角色重新渲染菜单
if (currentUser && fresh.role && currentUser.role !== fresh.role) {
localStorage.setItem('user', JSON.stringify(fresh));
currentUser = Object.assign({}, currentUser, fresh);
location.reload();
return;
}
currentUser = Object.assign({}, currentUser, fresh);
localStorage.setItem('user', JSON.stringify(currentUser));
const usernameEl = document.getElementById('username');
if (usernameEl) {
usernameEl.textContent = currentUser.nickname || currentUser.username;
@@ -170,11 +167,10 @@ async function logout() {
goLogin();
}
// 获取请求头
// 获取请求头(认证通过 HttpOnly Cookie 自动携带,只需 Content-Type)
function getHeaders() {
return {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('token')
'Content-Type': 'application/json'
};
}
@@ -1458,7 +1454,7 @@ async function uploadImageFile(file) {
const res = await fetch(`${API_BASE}/upload`, {
method: 'POST',
// 注意:上传 FormData 时不能手动设置 Content-Type,浏览器会自动处理 boundary
headers: { 'Authorization': 'Bearer ' + localStorage.getItem('token') },
// 认证通过 HttpOnly Cookie 自动携带
body: formData
});
+2 -1
View File
@@ -50,7 +50,8 @@
{{if index .PageSet "users"}}{{template "admin_modal_user" .}}{{end}}
{{if index .PageSet "themes"}}{{template "admin_modal_theme" .}}{{end}}
<script src="/static/admin/app.js?v=19"></script>
<script>window.__currentUser = {{.CurrentUser}};</script>
<script src="/static/admin/app.js?v=20"></script>
</body>
</html>
{{end}}
+10 -8
View File
@@ -27,10 +27,15 @@
</div>
<script>
// 已登录则直接进入后台
if (localStorage.getItem('token')) {
location.replace('/admin');
}
// 已登录则直接进入后台(通过 Cookie 自动认证,调用接口验证有效性)
(async function () {
try {
var res = await fetch('/api/auth/me');
if (res.ok) {
location.replace('/admin');
}
} catch (e) { /* 网络异常继续显示登录页 */ }
})();
function showError(msg) {
const el = document.getElementById('login-error');
@@ -55,10 +60,7 @@
});
const data = await res.json();
if (res.ok) {
localStorage.setItem('token', data.token);
localStorage.setItem('user', JSON.stringify(data.user));
// 菜单由登录接口返回,缓存供前端参考(页面菜单以服务端模板渲染为准)
localStorage.setItem('menus', JSON.stringify(data.menus || []));
// 服务端已通过 Set-Cookie 写入 JWT,直接跳转即可
location.href = '/admin';
} else {
showError(data.error || '登录失败');