登录后点赞/点踩按钮交互实现、防刷疑问及源码需求技术问询
登录后点赞/点踩功能实现方案及防刷策略
嘿,我来帮你梳理下这个功能的实现思路,还有你担心的登录后刷操作问题——这确实是这类互动功能的核心痛点,得从多层防护来解决。
一、核心功能实现步骤
前端部分:聚焦交互与身份传递
首先得确保只有登录用户能看到点赞/点踩按钮,未登录的话要么隐藏,要么点击时跳转到登录页。用户点击按钮后,要把用户身份凭证(比如存在localStorage里的JWT)、内容ID和**操作类型(like/dislike)**一起发给后端。拿到后端响应后,立刻更新UI状态(比如按钮变灰、显示“已点赞”,同步更新计数)。
给你个简单的前端示例代码:
// 假设登录后JWT存在localStorage中 const authToken = localStorage.getItem('userToken'); // 点赞按钮点击事件 document.getElementById('likeBtn').addEventListener('click', async () => { const postId = document.querySelector('[data-post-id]').dataset.postId; try { const response = await fetch(`/api/posts/${postId}/like`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${authToken}` } }); const result = await response.json(); if (result.success) { // 更新UI状态 document.getElementById('likeCount').textContent = result.newLikeCount; document.getElementById('likeBtn').disabled = true; document.getElementById('likeBtn').textContent = '已点赞'; // 顺便把点踩按钮恢复(如果之前点过的话) document.getElementById('dislikeBtn').disabled = false; document.getElementById('dislikeBtn').textContent = '点踩'; } else { alert(result.message || '点赞失败,请稍后重试'); } } catch (err) { console.error('请求出错:', err); alert('网络异常,请检查连接'); } }); // 点踩按钮的逻辑和点赞几乎一致,只是接口路径换成/dislike
后端部分:身份验证+数据校验+状态更新
后端的核心是先确认用户是登录状态,再校验用户有没有对当前内容做过相同操作,最后更新数据库并返回结果。这里用Node.js + Express + PostgreSQL举个例子:
1. 身份验证中间件
先写个JWT验证的中间件,确保只有合法登录用户能调用接口:
const jwt = require('jsonwebtoken'); const authenticateUser = (req, res, next) => { const authHeader = req.headers.authorization; const token = authHeader?.split(' ')[1]; if (!token) { return res.status(401).json({ success: false, message: '请先登录' }); } try { const decoded = jwt.verify(token, process.env.JWT_SECRET); req.userId = decoded.userId; // 把用户ID挂载到请求对象上 next(); } catch (err) { return res.status(403).json({ success: false, message: '登录凭证无效' }); } };
2. 点赞接口实现
const router = require('express').Router(); const db = require('../db'); // 你的数据库连接模块 const authenticateUser = require('../middleware/auth'); router.post('/posts/:postId/like', authenticateUser, async (req, res) => { const { postId } = req.params; const userId = req.userId; try { // 第一步:检查用户是否已经点赞过该内容 const existingLike = await db.query( 'SELECT id FROM user_post_interactions WHERE user_id = $1 AND post_id = $2 AND action = $3', [userId, postId, 'like'] ); if (existingLike.rows.length > 0) { return res.json({ success: false, message: '你已经点过赞啦' }); } // 第二步:如果用户之前点过踩,先取消点踩 const existingDislike = await db.query( 'SELECT id FROM user_post_interactions WHERE user_id = $1 AND post_id = $2 AND action = $3', [userId, postId, 'dislike'] ); if (existingDislike.rows.length > 0) { // 删除点踩记录 await db.query( 'DELETE FROM user_post_interactions WHERE id = $1', [existingDislike.rows[0].id] ); // 更新帖子的点踩数 await db.query( 'UPDATE posts SET dislike_count = dislike_count - 1 WHERE id = $1', [postId] ); } // 第三步:添加点赞记录,更新帖子点赞数 await db.query( 'INSERT INTO user_post_interactions (user_id, post_id, action) VALUES ($1, $2, $3)', [userId, postId, 'like'] ); const updatedPost = await db.query( 'UPDATE posts SET like_count = like_count + 1 WHERE id = $1 RETURNING like_count', [postId] ); res.json({ success: true, newLikeCount: updatedPost.rows[0].like_count, message: '点赞成功' }); } catch (err) { console.error('数据库操作出错:', err); res.status(500).json({ success: false, message: '服务器内部错误' }); } }); // 点踩接口逻辑类似,只是action换成dislike,计数加减相反 module.exports = router;
二、防刷问题的解决方案
你担心的“登录后轻易刷操作”确实要重视,单靠前端限制肯定不够,得从数据库、后端接口、前端交互三层入手:
1. 数据库层面:从根源限制重复操作
给user_post_interactions表加一个联合唯一约束:
ALTER TABLE user_post_interactions ADD CONSTRAINT unique_user_post_action UNIQUE (user_id, post_id, action);
这样就算后端逻辑有漏洞,数据库也会直接拒绝重复的操作请求,从根源上防止同一用户对同一内容的重复点赞/点踩。
2. 后端接口:限流+异常检测
- 接口限流:用限流中间件限制单个用户的请求频率,比如1分钟内最多5次点赞/点踩请求:
const rateLimit = require('express-rate-limit'); const interactionLimiter = rateLimit({ windowMs: 60 * 1000, // 1分钟窗口 max: 5, // 每个用户最多5次请求 keyGenerator: (req) => req.userId, // 用用户ID作为限流标识,比IP更准确 message: { success: false, message: '操作太频繁啦,休息一下再试吧' } }); // 给点赞/点踩接口加上限流 router.post('/posts/:postId/like', authenticateUser, interactionLimiter, async (req, res) => { // 接口逻辑... });
- 异常行为检测:记录用户的操作日志,比如如果某个用户10分钟内点赞了20个不同帖子,就标记为异常账号,后续可以要求输入验证码或者临时限制操作。
3. 前端交互:减少误操作和重复请求
- 按钮点击后立即禁用,直到后端返回结果,避免用户快速重复点击。
- 页面加载时,先请求后端获取用户对当前内容的操作状态,正确设置按钮的禁用状态(比如用户已经点赞过,就把按钮设为“已点赞”并禁用)。
三、总结
通过前端交互限制+后端身份验证+数据库唯一约束+接口限流的多层防护,就能有效防止登录用户刷点赞/点踩操作。核心思路是:确保每个用户对每个内容的操作是唯一的,同时限制短时间内的请求频率。
内容的提问来源于stack exchange,提问作者user9553360
相关产品推荐
相关产品推荐

