Go語(yǔ)言結(jié)合Redis實(shí)現(xiàn)用戶登錄次數(shù)限制功能
在登錄功能中,如果不加限制,攻擊者可能會(huì)通過(guò) 暴力 破解 嘗試大量密碼組合,帶來(lái)安全風(fēng)險(xiǎn)。
一個(gè)常見(jiàn)解決方案是:在一定時(shí)間內(nèi)限制用戶的登錄嘗試次數(shù),超過(guò)次數(shù)就鎖定一段時(shí)間。
Redis 的高性能和天然的過(guò)期機(jī)制,非常適合實(shí)現(xiàn)這種登錄限流功能。本文將通過(guò) Go + Redis 實(shí)現(xiàn)一個(gè) 用戶登錄次數(shù)限制 示例。
一、場(chǎng)景說(shuō)明
規(guī)則:每個(gè)用戶 1 分鐘內(nèi)最多嘗試登錄 5 次
超過(guò)限制:鎖定 1 分鐘,不允許繼續(xù)登錄
實(shí)現(xiàn)方式:
- 登錄時(shí),在 Redis 中維護(hù)一個(gè)計(jì)數(shù)器
- 如果計(jì)數(shù)器超過(guò)閾值,就禁止登錄
二、環(huán)境準(zhǔn)備
安裝依賴:
go get github.com/redis/go-redis/v9
確保本地或 Docker 中已運(yùn)行 Redis:
docker run -d -p 6379:6379 redis
三、Redis 工具初始化
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 連接成功")
}
四、實(shí)現(xiàn)登錄次數(shù)限制
// CheckLoginLimit 檢查用戶是否超過(guò)登錄限制
func CheckLoginLimit(username string) bool {
key := fmt.Sprintf("login:%s", username)
limit := 5 // 最大嘗試次數(shù)
blockTime := time.Minute // 超過(guò)限制后鎖定時(shí)間
// 自增計(jì)數(shù)器
count, err := rdb.Incr(ctx, key).Result()
if err != nil {
log.Println("Redis 錯(cuò)誤:", err)
return false
}
if count == 1 {
// 第一次設(shè)置過(guò)期時(shí)間
rdb.Expire(ctx, key, blockTime)
}
if count > int64(limit) {
return false // 超過(guò)限制
}
return true
}
五、模擬用戶登錄邏輯
// MockLogin 模擬登錄
func MockLogin(username, password string) {
if !CheckLoginLimit(username) {
log.Printf("用戶 %s 登錄失敗: 嘗試次數(shù)過(guò)多,請(qǐng)稍后再試\n", username)
return
}
// 假設(shè)正確密碼是 "123456"
if password == "123456" {
log.Printf("用戶 %s 登錄成功\n", username)
// 成功后清除計(jì)數(shù)器
rdb.Del(ctx, fmt.Sprintf("login:%s", username))
} else {
log.Printf("用戶 %s 登錄失敗: 密碼錯(cuò)誤\n", username)
}
}
六、測(cè)試效果
func main() {
initRedis()
for i := 1; i <= 7; i++ {
MockLogin("alice", "wrongpass")
}
}
運(yùn)行結(jié)果:
用戶 alice 登錄失敗: 密碼錯(cuò)誤
用戶 alice 登錄失敗: 密碼錯(cuò)誤
用戶 alice 登錄失敗: 密碼錯(cuò)誤
用戶 alice 登錄失敗: 密碼錯(cuò)誤
用戶 alice 登錄失敗: 密碼錯(cuò)誤
用戶 alice 登錄失敗: 嘗試次數(shù)過(guò)多,請(qǐng)稍后再試
用戶 alice 登錄失敗: 嘗試次數(shù)過(guò)多,請(qǐng)稍后再試
七、總結(jié)
通過(guò)本案例,我們實(shí)現(xiàn)了:
- 使用 Redis 存儲(chǔ)用戶登錄嘗試次數(shù)
- 借助
INCR+EXPIRE實(shí)現(xiàn)自動(dòng)計(jì)數(shù)和過(guò)期清理 - 登錄成功時(shí)清除計(jì)數(shù)器,避免誤封
應(yīng)用場(chǎng)景:
- 登錄安全限制(防止暴力 破解)
- API 請(qǐng)求限流
- 手機(jī)驗(yàn)證碼發(fā)送頻率控制
到此這篇關(guān)于Go語(yǔ)言結(jié)合Redis實(shí)現(xiàn)用戶登錄次數(shù)限制功能的文章就介紹到這了,更多相關(guān)Go用戶登錄次數(shù)限制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang goquery selector選擇器使用示例大全
這篇文章主要為大家介紹了golang goquery selector選擇器使用示例大全,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Golang新提案:panic?能不能加個(gè)?PanicError?
這篇文章主要為大家介紹了Golang的新提案關(guān)于panic能不能加個(gè)PanicError的問(wèn)題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
Go實(shí)現(xiàn)一個(gè)輕量級(jí)并發(fā)任務(wù)調(diào)度器(支持限速)
本文主要介紹了Go實(shí)現(xiàn)一個(gè)輕量級(jí)并發(fā)任務(wù)調(diào)度器(支持限速),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04

