项目优化方案之---实现单设备登录限制

对于一些付费会员或者一些商业项目,为了保证单个用户的账号权益不会被滥用,并且提高系统的安全性,我们会限制单个账号在同一时间内只能有一台设备登录,

来给系统添加共享账号的检测能能力

这里是根据jwt实现的,要实现单设备登录限制,这里最简单的方法也就是通过存入redis的方法,

生成jwt令牌之后,将令牌反馈前端的同时将其存入到redis中,而后在拦截器校验的时候,先校验jwt是否正确,再校验jwt是否和redis中的jwt一致,如果一致则说明是同一个用户。

上代码:

func LoginPwd(context *gin.Context) {var user entity.Userdb := common.GetDB()username := context.PostForm("username")password := context.PostForm("password")if len(username) < 5 || len(username) > 16 {response.Fail(context, "用户名长度在5-16之间", nil)return}if len(password) < 5 || len(password) > 16 {response.Fail(context, "密码长度在5-16之间", nil)return}if db.Where("name = ?", username).First(&user).RecordNotFound() {response.Fail(context, "用户名不存在", nil)return}if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {response.Fail(context, "密码错误", nil)return}client := common.CreateClient()生成唯一id//uuid := generateId()//common.SetKeyValue(client, UserField, strconv.FormatInt(uuid, 20))//返回tokentoken, err := common.ReleaseToken(user)if err != nil {response.Result(context, http.StatusInternalServerError, 500, "系统错误", nil)log.Println(err)return}err = common.SetKeyValueWithExpiration(client, JWT_USER_KEY, token, 1*time.Hour)if err != nil {response.Result(context, http.StatusInternalServerError, 500, "系统错误", nil)log.Println(err)return}// 在登录成功的响应中包含IP地址,或者根据需求进行记录、审计等操作log.Printf("User logged in with IP: %s", ip)response.Success(context, "登录成功", gin.H{"token": token,})}

中间件校验代码:

		//连接redisclient := common.CreateClient()//检查redis中是否有redisJwtValue, err := common.GetValue(client, JWT_USER_KEY)if err != nil {fmt.Println("获取jwt令牌失败", err)context.JSON(401, gin.H{"code": 401, "msg": "权限不足"})context.Abort()return}//比较jwt令牌,如果传来的令牌与redis中的令牌不同,则说明令牌已失效if JwtValue != tokenString {fmt.Println("jwt令牌已失效")context.JSON(401, gin.H{"code": 401, "msg": "权限不足"})context.Abort()return}

那么,如何实现在同一设备上登录不被顶掉呢?

比如同一个电脑不同的浏览器的话,登录的话就会有不同的jwt,此时如何让不同的浏览器能实现登录不被顶掉账号嘞(也就是单设备多客户端登录)

这里可以操作一下ip地址

在登录接口这里添加存储ip地址

// 获取客户端IPip := context.ClientIP()// 在登录成功的响应中包含IP地址,或者根据需求进行记录、审计等操作log.Printf("User logged in with IP: %s", ip)err = common.SetKeyValue(client, UserIp, ip)

        然后在中间件检测这里,如果ip相同,且jwt可以识别的情况下,就允许其直接通过,这样就可以实现,在同一设备上,登录同一个账号不被顶下去

func AuthMiddleware() gin.HandlerFunc {return func(context *gin.Context) {tokenString := context.GetHeader("Authorization")if tokenString == "" { //|| !strings.HasPrefix(tokenString, "Bearer "context.JSON(401, gin.H{"code": 401, "msg": "权限不足"})context.Abort()return}//tokenString = tokenString[7:]token, claims, err := common.ParseToken(tokenString)log.Println("token:", token, "claims:", claims, "err:", err)if err != nil || !token.Valid { //解析失败或者token无效context.JSON(401, gin.H{"code": 401, "msg": "权限不足"})context.Abort()return}//连接redisclient := common.CreateClient()//检查redis中是否有redisJwtValue, err := common.GetValue(client, JWT_USER_KEY)if err != nil {fmt.Println("获取jwt令牌失败", err)context.JSON(401, gin.H{"code": 401, "msg": "权限不足"})context.Abort()return}ip, _ := common.GetValue(client, UserIp)if ip == context.ClientIP() {//ip相等说明是同一个设备log.Println("ip相同,允许同设备放行")//获取用户信息userId := claims.UserIddb := common.GetDB()var user entity.Userdb.First(&user, userId)if user.ID == 0 { //用户不存在context.JSON(401, gin.H{"code": 401, "msg": "权限不足"})context.Abort()return}//用户存在,将user信息写入下上文context.Set("user", user)context.Next()}//比较jwt令牌,如果传来的令牌与redis中的令牌不同,则说明令牌已失效if JwtValue != tokenString {fmt.Println("jwt令牌已失效")context.JSON(401, gin.H{"code": 401, "msg": "权限不足"})context.Abort()return}//获取用户信息userId := claims.UserIddb := common.GetDB()var user entity.Userdb.First(&user, userId)if user.ID == 0 { //用户不存在context.JSON(401, gin.H{"code": 401, "msg": "权限不足"})context.Abort()return}//用户存在,将user信息写入下上文context.Set("user", user)context.Next()}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/36735.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8S集群进行分布式负载测试

使用K8S集群执行分布式负载测试 本教程介绍如何使用Kubernetes部署分布式负载测试框架&#xff0c;该框架使用分布式部署的locust 产生压测流量&#xff0c;对一个部署到 K8S集群的 Web 应用执行负载测试&#xff0c;该 Web 应用公开了 REST 格式的端点&#xff0c;以响应传入…

初探Xcode工具

初探Xcode工具 Xcode是苹果公司为Mac OS X和iOS平台开发软件的集成开发环境&#xff08;IDE&#xff09;。作为苹果开发者的首选工具&#xff0c;Xcode提供了一系列强大的功能&#xff0c;帮助开发者设计、编写、调试和发布应用程序。本文将对Xcode进行初步探索&#xff0c;介…

【吴恩达深度学习笔记系列】Logistic Regression 【理论】

Binary Classification: Logistic Regression: y ^ σ ( w T x b ) \hat{y}\sigma{(w^T xb)} y^​σ(wTxb) using sigmoid function σ 1 1 e − z \sigma \frac{1}{1e^{-z}} σ1e−z1​. 【torch.sigmoid(x)】 Sigmoid ( x ) 1 1 e − x \text{Sigmoid}(x)\frac{1}{…

综合评价 | 基于组合博弈赋权的物流系统综合评价(Matlab)

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 综合评价 | 基于组合博弈赋权的物流系统综合评价&#xff08;Matlab&#xff09; 组合博弈赋权&#xff08;Weighted Sum&#xff09;是一种常见的多目标决策方法&#xff0c;用于将多个目标指标进行综合评估和权衡…

Spring Boot中的国际化配置

Spring Boot中的国际化配置 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们将探讨如何在Spring Boot应用中实现国际化配置&#xff0c;使得应用能够轻松…

Android焦点窗口设定

我们经常会遇到一种Application does not hava focused window的ANR异常&#xff0c;这种异常一般是没有焦点窗口FocusedWindow导致,且这类异常只会发生在key事件的派发&#xff0c; 因为key事件是需要找到一个焦点窗口然后再派发&#xff0c;而触摸事件只需要找到当前显示的窗…

运维锅总详解HAProxy

本文尝试从HAProxy简介、HAProxy工作流程及其与Nginx的对比对其进行详细分析&#xff1b;在本文最后&#xff0c;给出了为什么Nginx比HAProxy更受欢迎的原因。希望对您有所帮助&#xff01; HAProxy简介 HAProxy&#xff08;High Availability Proxy&#xff09;是一款广泛使…

mysql 语句如何优化

MySQL语句的优化是一个复杂但重要的过程&#xff0c;因为它可以显著提高数据库的性能。以下是一些建议和方法&#xff0c;用于优化MySQL查询和语句&#xff1a; 1. 使用EXPLAIN分析查询 EXPLAIN是一个很有用的命令&#xff0c;它可以显示MySQL如何使用索引来处理SELECT语句。…

springboot在线考试 LW +PPT+源码+讲解

第三章 系统分析 3.1 可行性分析 一个完整的系统&#xff0c;可行性分析是必须要有的&#xff0c;因为他关系到系统生存问题&#xff0c;对开发的意义进行分析&#xff0c;能否通过本系统来补充线下在线考试管理模式中的缺限&#xff0c;去解决其中的不足等&#xff0c;通过对…

解释Android开发中常见的MVC、MVP和MVVM设计模式及其优缺点

在Android开发中&#xff0c;MVC&#xff08;Model-View-Controller&#xff09;、MVP&#xff08;Model-View-Presenter&#xff09;和MVVM&#xff08;Model-View-ViewModel&#xff09;是三种常见的设计模式&#xff0c;它们各自在解决不同问题时有其独特的优势和局限性。下…

Elasticsearch 聚合基础:terms、avg、sum 等

Elasticsearch 的聚合功能是其强大搜索和分析能力的重要组成部分&#xff0c;它允许用户对存储在索引中的数据执行复杂的分析操作&#xff0c;如计算平均值、求和、分组等。在本文中&#xff0c;我们将深入探讨 Elasticsearch 的聚合基础&#xff0c;特别是 terms、avg 和 sum …

阿里云开启ssl证书过程记录 NGINX

&#x1f91e;作者简介&#xff1a;大家好&#xff0c;我是思无邪&#xff0c;2024 毕业生&#xff0c;某厂 Go 开发工程师.。 &#x1f402;我的网站&#xff1a;https://www.yishanicode.top/ &#xff0c;持续更新&#xff0c;希望对你有帮助。 &#x1f41e;如果文章或网站…

【面试系列】数据科学家 高频面试题及详细解答

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&#xff1a;详细讲解AIGC的概念、核心技术、…

实验 1 图像基本操作

1. 实验目的 ①熟悉 Photoshop 基本操作&#xff1b; ②掌握 Matlab 、PythonOpenCV 中处理图像的基本方法&#xff1b; ③掌握图像的半调转换和抖动转换。 2. 实验内容 ①Photoshop 基本操作&#xff1a;打开图像文件&#xff0c;选择区域&#xff0c;旋转、裁剪图像、图层…

os实训课程模拟考试(大题复习)

目录 一、Linux操作系统 &#xff08;1&#xff09;第1关&#xff1a;Linux初体验 &#xff08;2&#xff09;第2关&#xff1a;Linux常用命令 &#xff08;3&#xff09;第3关&#xff1a;Linux 查询命令帮助语句 二、Linux之进程管理—&#xff08;重点&#xff09; &…

青岛网站建设一般多少钱

青岛网站建设的价格一般会根据网站的规模、功能、设计风格等因素来定&#xff0c;价格会存在着一定的差异。一般来说&#xff0c;一个简单的网站建设可能在数千元到一万元之间&#xff0c;而一个复杂的大型网站建设可能会需要数万元到数十万元不等。所以在选择网站建设服务时&a…

大模型RAG、ROG、RCG概念科普

大模型相关目录 大模型&#xff0c;包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步&#xff0c;扬帆起航。 大模型应用向开发路径&#xff1a;AI代理工作流大模型应用开发实用开源项目汇总大模…

LeetCode.76 最小覆盖子串

问题描述 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 "" 。 注意&#xff1a; 对于 t 中重复字符&#xff0c;我们寻找的子字符串中该字符数量必须不少于 t 中该字…

[Cloud Networking] BGP

1. AS (Autonomous System) 由于互联网规模庞大&#xff0c;所以网络会被分为许多 自治系统&#xff08;AS-Autonomous system&#xff09;。 所属类型ASN名称IPv4 数量IPv6数量运营商ISPAS3356LEVEL3 - Level 3 Parent, LLC, US29,798,83273,301,954,048互联网企业AS15169GO…

java接口自动化测试,怎样可以快速入门?

从0到1&#xff0c;快速入门Java接口自动化测试 Java接口自动化测试是一种自动化测试的方式&#xff0c;通过模拟用户发送HTTP请求并验证返回结果&#xff0c;来测试接口的正确性。它可以大大提高测试效率和覆盖率&#xff0c;减少人工测试的工作量。本文将从零开始&#xff0…