# 问题

\quad 最初,我建立 Hexo 博客的原因仅仅是觉得创建一个学习用的博客很酷,而且有成就感。不过,我并不想把博客公开,只想自己看看,自己琢磨。因此,一开始我并没有将博客托管到网上。然而,随着时间的推移,我发现每次打开本地博客都太麻烦,而且只能在建立博客的那台电脑上查看,实在不方便。于是,我先后将博客托管到了 Gitee Pages 和 GitHub Pages(在 Gitee 官方取消该功能后,我就不再使用了)。
\quad 托管到 GitHub 后,虽然可以随时随地登录查看博客,但因为有些内容写得太羞耻,我仍然担心被外人偶然看到(尽管这种可能性微乎其微)。作为一名搭建网站的外行爱好者,我一直在寻找方便的保密方法。
\quad 一开始我使用的是 hexo-blog-encrypt 插件来为博客的文章加密。然而,每篇文章都需要单独加密,打开时还需输入密码,而且有些内容(如图片)无法完全加载,每次都要刷新网页,这实在太麻烦了。后来,我考虑将博客放在阿里云等服务器上,设置一个加密登录,但作为外行,我完全无从下手,最终放弃了。
\quad 最近,我突发奇想地拷打了一下 ChatGPT,希望能找到简单的前端加密方法。令人惊喜的是,它真的给出了我满意的解决方案。

# 解决方案

\quad 在用户试图访问我的博客首页或者其他页面时,在每个页面加载的过程中,JavaScript 就会检查 localStorage 中是否存在 loggedIn 标志,若不存在则意味着用户尚未登录,用户会被重定向登录页面。用户在登录页面输入密码并提交表单,JavaScript 会将输入的密码与预设的正确密码进行比较。如果匹配,JavaScript 会在 localStorage 中设置 loggedIn 标志,并将用户重定向回首页。如果不匹配,则会提示用户密码错误。只有当用户成功登录( loggedIn 标志为 true )后,才能访问博客的其他内容。
\quad 并且游览器会储存登录的状态,意味着我下一次用自己的电脑的同一个游览器打开,就不需要再输入密码了,这很方便。

# 解决问题的具体操作

  1. 创建登录页面
    \quad 首先,在 hexo 的 source 目录中创建一个新的 HTML 文件,命名为 login.html ,内容如下:
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录</title>
    <style>
        body {
            margin: 0;
            display: grid; /* 使用 grid 布局 */
            place-items: center; /* 水平和垂直居中 */
            height: 100vh;
            background-color: #ffeef8;
            color: #d5006d;
            font-family: Arial, sans-serif;
        }
        .login-container {
            display: flex; /* 使用 flexbox */
            flex-direction: column; /* 垂直排列 */
            align-items: center; /* 水平居中 */
            background: rgba(255, 182, 193, 0.9);
            padding: 20px;
            border-radius: 10px;
            width: 100%; /* 容器宽度占满整个页面 */
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
        }
        input {
            text-align: center; /* 输入框内容居中 */
            font-size: 18px;
            padding: 8px;
            margin: 10px 0;
            width: 100%; /* 输入框宽度占满 */
            border: 2px solid #d5006d;
            border-radius: 5px;
            outline: none;
        }
        button {
            font-size: 18px;
            padding: 8px;
            width: 100%; /* 按钮宽度占满 */
            border: none;
            border-radius: 5px;
            cursor: pointer;
            background: #d5006d;
            color: white;
        }
        button:hover {
            background: #c4005a;
        }
        #sidebar, .header, .footer {
            display: none !important; /* 隐藏边栏、上栏和下栏 */
        }
    </style>
</head>
<body>
    <div class="login-container">
        <h1>要输入密码才能进入哦~~</h1>
        <input type="password" id="password" placeholder="密码" onkeypress="checkEnter(event)">
        <button onclick="checkPassword()">link start!!!</button>
    </div>
    <script>
        function checkPassword() {
            const password = document.getElementById('password').value;
            const correctPassword = '130'; // 设置你的密码
            if (password === correctPassword) {
                localStorage.setItem('loggedIn', 'true');
                window.location.href = '/'; // 登录成功后重定向到首页
            } else {
                alert('你的电波不对哦~~');
            }
        }
        function checkEnter(event) {
            if (event.key === 'Enter') {
                checkPassword(); // 按回车键时调用登录函数
            }
        }
        window.onload = function() {
            if (localStorage.getItem('loggedIn') === 'true') {
                window.location.href = '/'; // 已登录则跳转到首页
            }
        }
    </script>
</body>
</html>
  1. 添加路由保护
    \quad 在 hexo 的 主题文件的 layout/_partial/header.njk 文件中添加下述代码,以便在每次访问博客时检查是否已登录:
<script>
    window.onload = function() {
        if (!localStorage.getItem('loggedIn')) {
            window.location.href = '/login'; // 未登录时重定向到登录页面
        }
    }
</script>
  1. 添加路由映射
    \quad_config.yml 中添加路由映射,使其更友好和简洁。可以按如下方式添加:
routes:
  /login: /login.html

这样也就完成了,是不是很简单!

# 目前的成品

图1

\quad 目前的成品也就这样子,登录界面看起来还是比较丑的。等我以后有无聊的时间了,就再美化一下吧。

# 安全性注意事项

\quad 纵使这种加密方式我目前还算是比较满意的,但我也还是得清楚它的不安全性。其这种加密方式的原理可概况如下三点:

  • 前端存储:使用 localStorage 在用户的浏览器中存储登录状态。这种方法简单,适合不涉及敏感信息的场景。
  • JavaScript 验证:所有的密码验证和重定向都是在浏览器中通过 JavaScript 实现,不需要服务器端处理。这使得设置过程简单,但也意味着安全性较低。
  • 无后端支持:此方法不依赖于任何服务器端代码或数据库,因此适合静态网站(如 GitHub Pages)。

\quad 由于密码是明文存储在代码中的,且通过浏览器进行验证,因此方式并不安全。用户完全可以通过开发者工具查看和修改 localStorage 。总的来说,这种方法适合于简单的访问控制,但不适合保护需要更高安全性的内容。如果是稍微有一些专业知识,或者是一些有心人士,想要破解这种保护措施并不难。若想要更高级的保护措施,则需要考虑更安全的身份验证机制,例如后端用户验证、数据库存储密码、使用 HTTPS 等方式。这些方法能提供更好的保护,防止未授权访问。

\quad 目前,我的博客内容并不包含敏感或机密的信息,主要是一些学习笔记和个人感想。虽然里面有一些个人信息,但我觉得即使被外人看到,也不会对我造成实质伤害,顶多会让我感到羞愧。如果有一天,我的博客中出现了需要保密的敏感内容,我会考虑采取更高级的安全保护措施的。