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 请求限流
  • • 手机验证码发送频率控制
相关推荐
swipe12 分钟前
做多轮对话 Agent,为什么我建议把短期记忆放到 Redis
后端·面试·llm
程序员黑豆34 分钟前
AI全栈开发之Java:什么是JDK
前端·后端·ai编程
阿明在折腾1 小时前
从Canvas到AI模型:我在线工具站里的图片处理实战
前端·后端
tyung1 小时前
Go 手写 Wait-Free SPSC 无界队列:无 CAS、无锁、泛型节点池
数据结构·后端·go
Lucien3231 小时前
学完 Spring Boot 再看 FastAPI,我破防了
后端
小小龙学IT1 小时前
Go 语言后端开发:从并发模型到生产落地的工程实践
开发语言·后端·golang
程序员cxuan2 小时前
Agents.md 是什么
人工智能·后端·程序员
摇滚侠2 小时前
Java 零基础全套教程,类的加载过程与类加载器的理解,笔记 189
java·后端·intellij-idea
ServBay2 小时前
为什么我劝你不要在Mac上用Docker 进行本地 AI 开发
后端
蝎子莱莱爱打怪2 小时前
XZLL-IM干货系列 02|Protobuf 协议设计:从 JSON 切到二进制,每条消息省了 60%
后端·面试·架构