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 请求限流
  • • 手机验证码发送频率控制
相关推荐
勇哥java实战分享3 分钟前
短信平台 Pro 版本 ,比开源版本更强大
后端
学历真的很重要7 分钟前
LangChain V1.0 Context Engineering(上下文工程)详细指南
人工智能·后端·学习·语言模型·面试·职场和发展·langchain
计算机毕设VX:Fegn089510 分钟前
计算机毕业设计|基于springboot + vue二手家电管理系统(源码+数据库+文档)
vue.js·spring boot·后端·课程设计
上进小菜猪26 分钟前
基于 YOLOv8 的智能杂草检测识别实战 [目标检测完整源码]
后端
韩师傅1 小时前
前端开发消亡史:AI也无法掩盖没有设计创造力的真相
前端·人工智能·后端
栈与堆2 小时前
LeetCode-1-两数之和
java·数据结构·后端·python·算法·leetcode·rust
superman超哥2 小时前
双端迭代器(DoubleEndedIterator):Rust双向遍历的优雅实现
开发语言·后端·rust·双端迭代器·rust双向遍历
1二山似2 小时前
crmeb多商户启动swoole时报‘加密文件丢失’
后端·swoole
马卡巴卡2 小时前
Java CompletableFuture 接口与原理详解
后端
神奇小汤圆2 小时前
Java线程协作工具:CountDownLatch 、CyclicBarrier、Phaser、Semaphore 、Exchanger
后端