Go语言实战案例-Redis实现用户登录次数限制

在登录功能中,如果不加限制,攻击者可能会通过 暴力破解 尝试大量密码组合,带来安全风险。

一个常见解决方案是:在一定时间内限制用户的登录尝试次数,超过次数就锁定一段时间。

Redis 的高性能和天然的过期机制,非常适合实现这种登录限流功能。本文将通过 Go + Redis 实现一个 用户登录次数限制 示例。


一、场景说明

  • 规则:每个用户 1 分钟内最多尝试登录 5 次
  • 超过限制:锁定 1 分钟,不允许继续登录
  • 实现方式
    • • 登录时,在 Redis 中维护一个计数器
    • • 如果计数器超过阈值,就禁止登录

二、环境准备

安装依赖:

go 复制代码
go get github.com/redis/go-redis/v9

确保本地或 Docker 中已运行 Redis:

arduino 复制代码
docker run -d -p 6379:6379 redis

三、Redis 工具初始化

go 复制代码
package main

import (
    "context"
    "fmt"
    "github.com/redis/go-redis/v9"
    "log"
    "time"
)

var ctx = context.Background()
var rdb *redis.Client

func initRedis() {
    rdb = redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "",
        DB:       0,
    })

    if _, err := rdb.Ping(ctx).Result(); err != nil {
        log.Fatal("Redis 连接失败:", err)
    }
    log.Println("Redis 连接成功")
}

四、实现登录次数限制

go 复制代码
// CheckLoginLimit 检查用户是否超过登录限制
func CheckLoginLimit(username string) bool {
    key := fmt.Sprintf("login:%s", username)
    limit := 5             // 最大尝试次数
    blockTime := time.Minute // 超过限制后锁定时间

    // 自增计数器
    count, err := rdb.Incr(ctx, key).Result()
    if err != nil {
        log.Println("Redis 错误:", err)
        return false
    }

    if count == 1 {
        // 第一次设置过期时间
        rdb.Expire(ctx, key, blockTime)
    }

    if count > int64(limit) {
        return false // 超过限制
    }

    return true
}

五、模拟用户登录逻辑

c 复制代码
// MockLogin 模拟登录
func MockLogin(username, password string) {
    if !CheckLoginLimit(username) {
        log.Printf("用户 %s 登录失败: 尝试次数过多,请稍后再试\n", username)
        return
    }

    // 假设正确密码是 "123456"
    if password == "123456" {
        log.Printf("用户 %s 登录成功\n", username)
        // 成功后清除计数器
        rdb.Del(ctx, fmt.Sprintf("login:%s", username))
    } else {
        log.Printf("用户 %s 登录失败: 密码错误\n", username)
    }
}

六、测试效果

less 复制代码
func main() {
    initRedis()

    for i := 1; i <= 7; i++ {
        MockLogin("alice", "wrongpass")
    }
}

运行结果:

复制代码
用户 alice 登录失败: 密码错误
用户 alice 登录失败: 密码错误
用户 alice 登录失败: 密码错误
用户 alice 登录失败: 密码错误
用户 alice 登录失败: 密码错误
用户 alice 登录失败: 尝试次数过多,请稍后再试
用户 alice 登录失败: 尝试次数过多,请稍后再试

七、总结

通过本案例,我们实现了:

  • • 使用 Redis 存储用户登录尝试次数
  • • 借助 INCR + EXPIRE 实现自动计数和过期清理
  • • 登录成功时清除计数器,避免误封

应用场景

  • • 登录安全限制(防止暴力破解)
  • • API 请求限流
  • • 手机验证码发送频率控制
相关推荐
源代码•宸1 小时前
大厂技术岗面试之谈薪资
经验分享·后端·面试·职场和发展·golang·大厂·职级水平的薪资
晚霞的不甘1 小时前
CANN 编译器深度解析:UB、L1 与 Global Memory 的协同调度机制
java·后端·spring·架构·音视频
喵叔哟2 小时前
06-ASPNETCore-WebAPI开发
服务器·后端·c#
Charlie_lll2 小时前
力扣解题-移动零
后端·算法·leetcode
打工的小王3 小时前
Spring Boot(三)Spring Boot整合SpringMVC
java·spring boot·后端
80530单词突击赢5 小时前
JavaWeb进阶:SpringBoot核心与Bean管理
java·spring boot·后端
爬山算法5 小时前
Hibernate(87)如何在安全测试中使用Hibernate?
java·后端·hibernate
WeiXiao_Hyy5 小时前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
苏渡苇5 小时前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
long3165 小时前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法