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 请求限流
  • • 手机验证码发送频率控制
相关推荐
IT_陈寒2 小时前
用了Proxy才发现以前的JavaScript白写了
前端·人工智能·后端
唐青枫2 小时前
别把 ArrayList 当成会自动管理内存的 List:Zig 动态数组从入门到实战
后端
鸿蒙开发3 小时前
我为 HarmonyOS 做了一个统一大模型 SDK:@hmkit/ai 正式开源
后端
猪是念来过倒3 小时前
Semaphore 与 RateLimiter:并发控制双雄详解
后端
掘金者阿豪3 小时前
异构数据同步最怕什么?不是同步慢,而是数据对不上
后端
程序员cxuan4 小时前
Claude 官方的学习教程,太强了。
人工智能·后端·程序员
老孙讲技术4 小时前
把工地遮挡和掉线接进项目部:setMessageCallback 订 alarm 与 deviceStatus
后端·物联网·音视频开发
老孙讲技术4 小时前
关店后有人进门,监控值班群却没响:用 setMessageCallback 订 human,再用 aiHuman 打开人形
后端·物联网·音视频开发
LEE4 小时前
原来 Claude Code 最厉害的工具,一行代码都不写
前端·后端
老孙讲技术4 小时前
把园区几百路摄像头收进值班台账:bindDevice 入账与 listDeviceDetailsByPage 翻页
后端·物联网·音视频开发