用go封装一下封禁功能
思路
封禁业务也是在一般项目中比较常见的业务。我们也将它封装在库中作为功能之一。
我们同样使用adapter作为底层的存储结构,将封禁标示作为k-v结构存储。
把id和服务名称service作为key,把封禁的级别level作为value,以此我们能实现一些比较常见的封禁业务。
实现
首先就是封禁方法,首先当然要校验一下参数,然后存储封禁标识。要注意的就是level要大于等于1,在封禁后也要调用我们的logger和watcher。
// Banned ban user, if time == 0,the timeout is not set
func (e *Enforcer) Banned(id string, service string, level int, time int64) error {if id == "" || service == "" {return fmt.Errorf("parameter cannot be nil")}if level < 1 {return fmt.Errorf("unexpected level = %v, level must large or equal 1", level)}err := e.adapter.SetStr(e.spliceBannedKey(id, service), strconv.Itoa(level), time)if err != nil {return err}// callbacke.logger.Ban(e.loginType, id, service, level, time)if e.watcher != nil {e.watcher.Ban(e.loginType, id, service, level, time)}return nil
}
再来就是解除封禁的实现,很简单,只要删除我们封禁存的那条记录就可以了。
// UnBanned Unblock user account
func (e *Enforcer) UnBanned(id string, services ...string) error {if id == "" {return fmt.Errorf("parmeter id can not be nil")}if len(services) == 0 {return fmt.Errorf("parmeter services length can not be 0")}for _, service := range services {err := e.adapter.DeleteStr(e.spliceBannedKey(id, service))if err != nil {return err}e.logger.UnBan(e.loginType, id, service)if e.watcher != nil {e.watcher.UnBan(e.loginType, id, service)}}return nil
}
接着还需要提供几个方便使用的方法
分别用来判断是否被封禁,获得封禁的级别,获得封禁的剩余时间三个方法
判断是否被封禁
// IsBanned if banned return true, else return false
func (e *Enforcer) IsBanned(id string, services string) bool {s := e.adapter.GetStr(e.spliceBannedKey(id, services))return s != ""
}
获得封禁的级别
go复制代码// GetBannedLevel get banned level
func (e *Enforcer) GetBannedLevel(id string, service string) (int64, error) {str := e.adapter.GetStr(e.spliceBannedKey(id, service))if str == "" {return 0, fmt.Errorf("loginId = %v, service = %v is not banned", id, service)}time, err := strconv.ParseInt(str, 10, 64)if err != nil {return 0, err}return time, nil
}
获得封禁的剩余时间
go复制代码// GetBannedTime get banned time
func (e *Enforcer) GetBannedTime(id string, service string) int64 {timeout := e.adapter.GetStrTimeout(e.spliceBannedKey(id, service))return timeout
}
有了这几个方法,我们就可以使用token-go更为方便是实现登录业务了。
对于一般的业务,我们其实可以无视封禁级别。只需要使用Banned()进行封禁,在每个需要校验是否被封禁的业务前进行IsBanned()的判断就行了。
测试例子:
go复制代码func TestEnforcer_Banned(t *testing.T) {err, enforcer, _ := NewTestEnforcer(t)if err != nil {t.Fatalf("NewTestEnforcer() failed: %v", err)}err = enforcer.Banned("1", "comment", 1, 100)if err != nil {t.Fatalf("Banned() failed: %v", err)}isBanned := enforcer.IsBanned("1", "comment")if !isBanned {t.Errorf("unexpected isBanned is false")}err = enforcer.UnBanned("1", "comment")if err != nil {t.Fatalf("UnBanned() failed: %v", err)}isBanned = enforcer.IsBanned("1", "comment")if isBanned {t.Errorf("unexpected isBanned is false")}
}
当然我们对于一个业务会有一些较为复杂的封禁,比如discuss交流业务,如果级别为1我们会禁止评论,如果级别为2我们会禁止评论和点赞,级别为3我们会禁止评论、点赞和收藏。
这个时候我们只需要再加上GetBannedLevel(),在每个业务前获取封禁级别进行判断就可以简单的实现了。
相关文章:
用go封装一下封禁功能
思路 封禁业务也是在一般项目中比较常见的业务。我们也将它封装在库中作为功能之一。 我们同样使用adapter作为底层的存储结构,将封禁标示作为k-v结构存储。 把id和服务名称service作为key,把封禁的级别level作为value,以此我们能实现一些比…...

loki 如何格式化日志
部署 grafana-loki 首先介绍一下如何部署 官方文档:部署 grafana-loki 部署命令 设置集群的存储类,如果有默认可以不设置设置命名空间 helm install loki oci://registry-1.docker.io/bitnamicharts/grafana-loki --set global.storageClasslocal -n …...
在Linux上使用mysqldump备份MySQL数据库的详细步骤
MySQL数据库备份是确保数据安全性的关键步骤之一。在Linux系统上,使用mysqldump工具是一种常见、可靠的方法,它能够导出数据库的结构和数据,以便在需要时进行还原。以下是详细的备份步骤: 步骤 1:登录到MySQL服务器 …...
神经网络基础
神经网络 引言 神经网络的历史背景 神经网络的概念最早可以追溯到20世纪40年代,当时的科学家们受到生物神经系统的启发,尝试模拟人脑的信息处理方式。在接下来的几十年里,这个领域经历了多次兴衰。尽管在最初几十年内进展缓慢,…...
你好,C++(2)1.3 C++世界版图1.4 如何学好C++
1.3 C世界版图 C语言的发展过程,不仅是一个特性不断增加、内容不断丰富的过程,更是一个在应用领域中不断攻城略地的过程。在其30余年的发展过程中,C在多个应用领域都得到了广泛的应用和发展。无论是在最初的UNIX/Linux操作系统上,…...
Ceph入门到精通- smartctl -l error检查硬盘指标
“smartctl -l error” 是一个 Linux 命令,用于查看磁盘驱动器的 SMART (Self-Monitoring, Analysis and Reporting Technology) 错误日志。SMART 是一种技术,能够监测硬盘驱动器的状态并提供关于硬盘健康状况的信息。 运行该命令后,你将看到…...

【LeetCode刷题】-- 161.相隔为1的编辑距离
161.相隔为1的编辑距离 方法:一次遍历 首先,我们要确认字符串的长度不会相差太远。如果长度差了2个或更多字符,那么 s 和 t 就不可能是一次编辑之差的字符串。 接下来,我们假设 s 的长度总是短于或等于 t 的长度。如果不是这样&…...

SQL进阶理论篇(八):SQL查询的IO成本
文章目录 简介数据库缓冲池查看缓冲池的大小数据页加载的三种方式通过 last_query_cost 统计 SQL 语句的查询成本总结参考文献 简介 本节将介绍磁盘IO是如何加载数据的,重点介绍一下数据库缓冲池的概念。主要包括: 什么是数据库缓冲池,它在…...

宝塔PostgreSQL设置数据库远程访问
宝塔PostgreSQL设置数据库远程访问 宝塔的PostgreSQL1. 添加数据库2. 打开PostgreSQL设置界面3. 修改配置4. 重载配置/重启数据库 Docker的PostgreSQL1. postgresql.conf2. pg_hba.conf3. 重启数据库 注意其他问题 宝塔PostgreSQL设置数据库远程访问?docker容器Post…...

蓝牙协议栈学习笔记
蓝牙协议栈学习笔记 蓝牙简介 蓝牙工作在全球通用的 2.4GHz ISM(即工业、科学、医学)频段,使用 IEEE802.11 协议 蓝牙 4.0 是迄今为止第一个蓝牙综合协议规范,将三种规格集成在一起。其中最重要的变化就是 BLE(Blue…...

XXE利用的工作原理,利用方法及防御的案例讲解
XXE(XML外部实体注入)利用是一种网络安全攻击手段,其中攻击者利用XML解析器处理外部实体的方式中的漏洞。这种攻击主要针对的是那些使用XML来处理数据的应用程序,尤其是当这些应用程序没有正确限制外部实体的处理时。通过XXE利用&…...

jpa 修改信息拦截
实现目标springbootJPA 哪个人,修改了哪个表的哪个字段,从什么值修改成什么值 import jakarta.persistence.*; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; im…...

JavaEE 09 锁策略
1.锁策略 1.1 乐观锁与悲观锁 其实前三个锁是同一种锁,只是站在不同的角度上去进行描述,此处的乐观与悲观其实是指在预测的角度上看会发生锁竞争的概率大小,概率大的则是悲观锁,概率小的则是乐观锁 乐观锁在加锁的时候就会做较少的事情,加锁的速度较快,但是消耗的cpu资源等也会…...

javacv的视频截图功能
之前做了一个资源库的小项目,因为上传资源文件包含视频等附件,所以就需要时用到这个功能。通过对视频截图,然后作为封面缩略图,达到美观效果。 首先呢,需要准备相关的jar包,之前我用的是低版本的1.4.2&…...

Fiddler中AutoResponder的简单使用
AutoResponder,自动回复器,用于将 HTTP 请求重定向为指定的返回类型。 这个功能有点像是一个代理转发器,可以将某一请求的响应结果替换成指定的资源,可以是某个页面也可以是某个本地文件 1.使用 打开“Fiddler”,点击…...

K8S(一)—安装部署
目录 安装部署前提以下的操作指导(在master)之前都是三台机器都需要执行 安装docker服务下面的操作仅在k8smaster执行 安装部署 前提 以下的操作指导(在master)之前都是三台机器都需要执行 关闭防火墙 [rootk8smaster ~]# vim /etc/selinux/config [rootk8smaster ~]# swa…...
Kubernetes Pod 网段与主机内网网段互通
开发环境的需求 开发环境部署 K8s 后,服务器会部署在 K8s 里,通常 Pod 网段被隔离,主机无法访问 实际开发需求,往往需要当前开发调试的服务主机本地部署,其他服则在 K8s 内 因此,使用 K8s ,必…...

go学习redis的学习与使用
文章目录 一、redis的学习与使用1.Redis的基本介绍2.Redis的安装下载安装包即可3.Redis的基本使用1)Redis的启动:2)Redis的操作的三种方式3)说明:Redis安装好后,默认有16个数据库,初始默认使用0…...

娱乐新拐点:TikTok如何改变我们的日常生活?
在数字时代的浪潮中,社交媒体平台不断涌现,其中TikTok以其独特的短视频内容在全球范围内掀起了一场娱乐革命。本文将深入探讨TikTok如何改变我们的日常生活,从社交互动、文化传播到个人创意表达,逐步改写了娱乐的新篇章。 短视频潮…...

【Nginx】Nginx了解(基础)
文章目录 Nginx产生的原因Nginx简介Nginx的作用反向代理负载均衡策略动静分离 Nginx的Windows下的安装Linux下的安装Nginx常用命令 负载均衡功能演示 Nginx产生的原因 背景 一个公司的项目刚刚上线的时候,并发量小,用户使用的少,所以在低并发…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...

嵌入式学习之系统编程(九)OSI模型、TCP/IP模型、UDP协议网络相关编程(6.3)
目录 一、网络编程--OSI模型 二、网络编程--TCP/IP模型 三、网络接口 四、UDP网络相关编程及主要函数 编辑编辑 UDP的特征 socke函数 bind函数 recvfrom函数(接收函数) sendto函数(发送函数) 五、网络编程之 UDP 用…...

02.运算符
目录 什么是运算符 算术运算符 1.基本四则运算符 2.增量运算符 3.自增/自减运算符 关系运算符 逻辑运算符 &&:逻辑与 ||:逻辑或 !:逻辑非 短路求值 位运算符 按位与&: 按位或 | 按位取反~ …...

Mysql故障排插与环境优化
前置知识点 最上层是一些客户端和连接服务,包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念,为通过安全认证接入的客户端提供线程。同样在该层上可…...

MCP和Function Calling
MCP MCP(Model Context Protocol,模型上下文协议) ,2024年11月底,由 Anthropic 推出的一种开放标准,旨在统一大模型与外部数据源和工具之间的通信协议。MCP 的主要目的在于解决当前 AI 模型因数据孤岛限制而…...