1301
This commit is contained in:
1 parent
167a284da9
commit
865d9ec984
9 files changed
+263
-45
No files matched your search
@@ -48,23 +48,6 @@ server {
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
# Hugo 预览代理(不需要认证)
|
||||
# Hugo 静态资源
|
||||
location ~ ^/(css|js|font|fonts|image/background|image/avatar|image/reward|emotion)/ {
|
||||
auth_request off;
|
||||
proxy_pass http://write-server:1313;
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
# Hugo 页面预览
|
||||
location /preview/ {
|
||||
auth_request off;
|
||||
rewrite ^/preview/(.*)$ /$1 break;
|
||||
proxy_pass http://write-server:1313;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
# 所有其他请求通过 auth_request 验证
|
||||
location / {
|
||||
auth_request /auth/internal;
|
||||
|
||||
@@ -39,6 +39,26 @@ h1{font-size:20px;color:#1d3d6c;margin-bottom:4px;font-weight:700}
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
var EXPIRE_MS = 3 * 60 * 60 * 1000; // 3小时过期
|
||||
|
||||
function getAuth() {
|
||||
try {
|
||||
var raw = localStorage.getItem('wauth');
|
||||
if (!raw) return null;
|
||||
var data = JSON.parse(raw);
|
||||
if (!data.token || !data.time) { localStorage.removeItem('wauth'); return null; }
|
||||
if (Date.now() - data.time > EXPIRE_MS) { localStorage.removeItem('wauth'); return null; }
|
||||
return data.token;
|
||||
} catch(e) {
|
||||
localStorage.removeItem('wauth');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function setAuth(tok) {
|
||||
localStorage.setItem('wauth', JSON.stringify({ token: tok, time: Date.now() }));
|
||||
}
|
||||
|
||||
document.getElementById('form').addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
var btn = document.getElementById('btn');
|
||||
@@ -52,22 +72,16 @@ document.getElementById('form').addEventListener('submit', async function(e) {
|
||||
var tok = btoa(u + ':' + p);
|
||||
|
||||
try {
|
||||
// 验证凭据
|
||||
var res = await fetch('/auth/check', {
|
||||
headers: { 'Authorization': 'Basic ' + tok }
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error('auth failed');
|
||||
}
|
||||
if (!res.ok) throw new Error('auth failed');
|
||||
|
||||
// 存储凭据
|
||||
localStorage.setItem('wauth', tok);
|
||||
setAuth(tok);
|
||||
|
||||
// 注册 Service Worker
|
||||
if ('serviceWorker' in navigator) {
|
||||
var reg = await navigator.serviceWorker.register('/sw.js');
|
||||
// 等待 SW 激活
|
||||
if (reg.installing) {
|
||||
await new Promise(function(resolve) {
|
||||
reg.installing.addEventListener('statechange', function() {
|
||||
@@ -75,18 +89,13 @@ document.getElementById('form').addEventListener('submit', async function(e) {
|
||||
});
|
||||
});
|
||||
}
|
||||
// 发送 token 给 SW
|
||||
var sw = reg.active || reg.waiting || reg.installing;
|
||||
if (sw) {
|
||||
sw.postMessage({ type: 'SET_TOKEN', token: tok });
|
||||
}
|
||||
// 确保 SW 控制当前页面
|
||||
if (sw) sw.postMessage({ type: 'SET_TOKEN', token: tok });
|
||||
if (navigator.serviceWorker.controller) {
|
||||
navigator.serviceWorker.controller.postMessage({ type: 'SET_TOKEN', token: tok });
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转到主页
|
||||
location.href = '/';
|
||||
} catch (err2) {
|
||||
err.style.display = 'block';
|
||||
@@ -97,7 +106,7 @@ document.getElementById('form').addEventListener('submit', async function(e) {
|
||||
|
||||
// 已登录则验证后跳转
|
||||
(function(){
|
||||
var tok = localStorage.getItem('wauth');
|
||||
var tok = getAuth();
|
||||
if (!tok) return;
|
||||
fetch('/auth/check', { headers: { 'Authorization': 'Basic ' + tok } }).then(function(r) {
|
||||
if (r.ok) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
const CACHE = 'v1';
|
||||
const LOGIN = '/login.html';
|
||||
const EXPIRE_MS = 3 * 60 * 60 * 1000; // 3小时
|
||||
|
||||
self.addEventListener('install', () => self.skipWaiting());
|
||||
|
||||
@@ -14,10 +15,15 @@ self.addEventListener('fetch', e => {
|
||||
|
||||
e.respondWith((async () => {
|
||||
const token = self.__auth_token;
|
||||
if (!token) {
|
||||
// 尝试从 IndexedDB/localStorage 读取(SW 中无法直接访问 localStorage)
|
||||
// 依赖客户端页面消息传递 token
|
||||
return fetch(req);
|
||||
const tokenTime = self.__auth_time || 0;
|
||||
|
||||
if (!token || (Date.now() - tokenTime > EXPIRE_MS)) {
|
||||
// token 过期或不存在,重定向到登录页
|
||||
if (token) {
|
||||
self.__auth_token = null;
|
||||
self.__auth_time = 0;
|
||||
}
|
||||
return Response.redirect(LOGIN, 302);
|
||||
}
|
||||
|
||||
const headers = new Headers(req.headers);
|
||||
@@ -25,6 +31,8 @@ self.addEventListener('fetch', e => {
|
||||
const res = await fetch(new Request(req, { headers }));
|
||||
|
||||
if (res.status === 401) {
|
||||
self.__auth_token = null;
|
||||
self.__auth_time = 0;
|
||||
return Response.redirect(LOGIN, 302);
|
||||
}
|
||||
return res;
|
||||
@@ -35,8 +43,10 @@ self.addEventListener('fetch', e => {
|
||||
self.addEventListener('message', e => {
|
||||
if (e.data && e.data.type === 'SET_TOKEN') {
|
||||
self.__auth_token = e.data.token;
|
||||
self.__auth_time = Date.now();
|
||||
}
|
||||
if (e.data && e.data.type === 'CLEAR_TOKEN') {
|
||||
self.__auth_token = null;
|
||||
self.__auth_time = 0;
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user