博客:八股文网站验证码解锁与JWT登录机制解析/前端Vuex实现

博客:八股文网站验证码解锁与JWT登录机制解析

一、八股文网站的验证码解锁功能实现原理

许多技术类博客或八股文网站通过"关注公众号后输入验证码解锁全文"的功能增加用户粘性。这种机制涉及前后端协作,以下是实现方式及相关问题的详细分析:

1. 实现方式

用户访问文章页面时,前端初始只加载部分内容,全文被隐藏或加密。后端控制解锁逻辑,流程如下:

  • 关注公众号:用户关注后获取验证码。
  • 输入验证码:前端将验证码发送至后端。
  • 后端验证:后端校验验证码(通过公众号接口或预设值),验证通过后返回解锁令牌(token)。
  • 前端存储与解锁:前端将token存储在本地(如localStorage或cookie),用以解锁全文。

若每个页面访问都需携带token请求权限,会导致:

  • 用户体验差:每次跳转都需等待验证。
  • 后端压力大:频繁请求增加服务器负担。

2. 优化体验:前端缓存解锁状态

为提升体验,常见做法是前端在首次验证成功后缓存全文或解锁状态,后续页面访问直接使用本地数据,避免重复请求。以Vue为例,具体实现如下:

Vue中的实现

假设使用Vue开发前端,可以通过Vuex(或Pinia)管理状态,结合localStorage存储token和解锁内容。以下是详细步骤:

  • 首次验证
    • 用户输入验证码,前端发送请求至后端。
    • 后端返回token(包含过期时间戳,如JWT中的exp)和全文内容。
    • 前端将token和内容存入localStorage,并更新Vuex状态。
  • 状态管理
    • Vuex存储一个isUnlocked标志和全文内容。
    • 页面组件根据isUnlocked决定显示部分还是全文。
  • 时间限制与token验证
    • 在Vue组件的createdmounted钩子中,检查localStorage中的token。
    • 解析token,提取过期时间戳(exp),与当前时间戳(Date.now())比较。
    • 若当前时间大于exp,则删除localStorage中的token和内容,更新Vuex状态为未解锁,提示用户重新请求token。
示例代码(Vue + Vuex)
javascript 复制代码
// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    isUnlocked: false,
    fullContent: ''
  },
  mutations: {
    setUnlocked(state, { isUnlocked, content }) {
      state.isUnlocked = isUnlocked;
      state.fullContent = content;
    }
  },
  actions: {
    checkToken({ commit }) {
      const token = localStorage.getItem('unlockToken');
      if (token) {
        const payload = JSON.parse(atob(token.split('.')[1])); // 解析JWT的Payload
        const currentTime = Math.floor(Date.now() / 1000); // 当前时间戳(秒)
        if (currentTime < payload.exp) {
          const content = localStorage.getItem('fullContent');
          commit('setUnlocked', { isUnlocked: true, content });
        } else {
          localStorage.removeItem('unlockToken');
          localStorage.removeItem('fullContent');
          commit('setUnlocked', { isUnlocked: false, content: '' });
        }
      }
    },
    unlockContent({ commit }, { token, content }) {
      localStorage.setItem('unlockToken', token);
      localStorage.setItem('fullContent', content);
      commit('setUnlocked', { isUnlocked: true, content });
    }
  }
});

// App.vue
<template>
  <div>
    <div v-if="isUnlocked">{{ fullContent }}</div>
    <div v-else>
      <p>部分内容...</p>
      <input v-model="code" placeholder="输入验证码" />
      <button @click="submitCode">解锁</button>
    </div>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex';

export default {
  data() {
    return { code: '' };
  },
  computed: mapState(['isUnlocked', 'fullContent']),
  created() {
    this.checkToken(); // 页面加载时检查token
  },
  methods: {
    ...mapActions(['checkToken', 'unlockContent']),
    async submitCode() {
      const res = await fetch('/api/unlock', {
        method: 'POST',
        body: JSON.stringify({ code: this.code })
      });
      const { token, content } = await res.json();
      this.unlockContent({ token, content });
    }
  }
};
</script>
  • 逻辑说明
    • 每次页面加载时,checkToken检查token是否过期。
    • 若未过期,直接使用缓存内容;若过期,清除缓存,恢复未解锁状态。
    • 用户提交验证码后,存储新token和内容,并更新状态。
保证限定时间访问

通过token中的exp字段和前端时间戳比较,确保用户只能在限定时间内访问:

  • 后端设置 :生成token时设置exp(如1小时后过期)。
  • 前端校验 :每次访问时比较exp与当前时间,过期则删除权限。
  • 安全性 :因token由后端签名,前端无法篡改exp,保证时间限制有效。

3. LocalStorage与Cookie的区别

  • LocalStorage:容量大(5-10MB),仅客户端访问,适合存储token和内容。
  • Cookie:容量小(4KB),自动随请求发送,适合服务端验证但增加请求开销。 在此场景,localStorage更适合缓存解锁状态,减少后端压力。

4. JWT与无状态token

JWT通过签名实现无状态验证。若不使用Redis,可在Payload中嵌入exp,前端自行判断过期。篡改JWT会导致签名失效,除非密钥泄露。


二、JWT登录的原理与篡改问题

1. JWT登录原理

  • 用户登录后,服务端生成JWT,前端存储并携带于请求中。
  • 服务端验证签名和exp,确认合法性。
  • 前端可缓存权限状态,减少请求。

2. JWT被篡改的问题

  • 篡改Payload:签名失效,验证失败。
  • 密钥泄露:需确保密钥安全。
  • 前端续约:无密钥无法伪造。

3. 应对措施

  • 缓存优化:前端缓存状态,减少验证频率。
  • 短有效期:搭配刷新机制。
  • HTTPS:防止窃取。

总结

八股文网站的解锁功能通过token实现,Vue中可利用localStorage和Vuex缓存状态,通过exp与时间戳比较限制访问时间。JWT提供无状态认证,结合前端优化可提升体验并减轻后端压力。

相关推荐
神奇的程序员5 小时前
从已损坏的备份中拯救数据
运维·后端·前端工程化
oden6 小时前
AI服务商切换太麻烦?一个AI Gateway搞定监控、缓存和故障转移(成本降40%)
后端·openai·api
李慕婉学姐7 小时前
【开题答辩过程】以《基于Android的出租车运行监测系统设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·后端·vue
m0_740043737 小时前
SpringBoot05-配置文件-热加载/日志框架slf4j/接口文档工具Swagger/Knife4j
java·spring boot·后端·log4j
招风的黑耳8 小时前
我用SpringBoot撸了一个智慧水务监控平台
java·spring boot·后端
Miss_Chenzr8 小时前
Springboot优卖电商系统s7zmj(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
期待のcode8 小时前
Springboot核心构建插件
java·spring boot·后端
2501_921649498 小时前
如何获取美股实时行情:Python 量化交易指南
开发语言·后端·python·websocket·金融
serendipity_hky9 小时前
【SpringCloud | 第5篇】Seata分布式事务
分布式·后端·spring·spring cloud·seata·openfeign
五阿哥永琪9 小时前
Spring Boot 中自定义线程池的正确使用姿势:定义、注入与最佳实践
spring boot·后端·python