最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談go token需要存表嗎

 更新時間:2026年07月19日 10:20:15   作者:leijmdas  
文清晰對比了短時效AccessToken和長時效RefreshToken的存儲策略,告訴你為什么AccessToken依賴本地驗簽就夠了,而RefreshToken必須持久化以支持撤銷、輪換和防重放攻擊

這個問題問得很精準。結(jié)合你上一個關(guān)于 Refresh Token 的問題,我直接給你一個明確且分層的答案:

Access Token(短時效令牌):通常不需要存表。
Refresh Token(長時效令牌):必須存表(或 Redis)。

下面我詳細解釋為什么,以及這兩種 Token 在 Go 項目中的標準處理范式。

1. Access Token(短令牌,比如 15分鐘):絕不存表

這是 Go 社區(qū)和業(yè)界的最佳實踐。

原因:Access Token 的使命是高頻攜帶(每次 API 請求都要帶)。如果每次都查數(shù)據(jù)庫或 Redis 校驗,數(shù)據(jù)庫連接池會迅速耗盡,性能直接崩盤。

校驗方式純本地無狀態(tài)校驗。

  • 收到 Token 后,只用密鑰在內(nèi)存中驗簽(jwt.Parse)。
  • 檢查 exp(過期時間)是否在當下之后。
  • 驗簽通過即信任,完全不查庫。

如何讓 Access Token “失效”?:不存表意味著你無法主動刪除它。解決方法是縮短過期時間(比如 5-15分鐘),讓其自然死亡。如果遇到用戶修改密碼或封號等緊急情況,可以在網(wǎng)關(guān)層維護一個內(nèi)存黑名單(或 Redis 黑名單),只針對極少數(shù)異常用戶進行查庫攔截。

2. Refresh Token(長令牌,比如 7天):必須存表(或 Redis)

正如我上個回答所說,它存表的目的不是為了驗簽,而是為了控制狀態(tài)

主動撤銷(退出登錄):用戶點退出,你在表中把該 jti 標記為 revoked,下次刷新時拒掉。

絕對過期清理:依賴數(shù)據(jù)庫的 expires_at 索引,定時任務(wù)掃表清理,比依賴 JWT 自帶的 exp 更可靠(因為服務(wù)端時間可控)。

Refresh Token 輪換(旋轉(zhuǎn)):每次刷新時,舊 Token 作廢,生成新 Token 入庫。如果同一個舊 Token 被使用兩次,說明被盜用,直接清空該用戶所有 Token。

3. 特殊情況:什么時候 Access Token 也需要“存”?

如果你的業(yè)務(wù)有極端的即時封禁需求(比如管理員封號后,要求該用戶 1 秒內(nèi)所有操作失效),而 Access Token 過期時間又設(shè)得比較長(比如 1 小時),那么你可以采用 Redis 布隆過濾器 + 黑名單 方案:

  • 封禁時,將 user_id 或 token_jti 放入 Redis 黑名單(設(shè)置過期時間為 Access Token 的剩余有效期)。
  • 在 Go 中間件里,驗簽通過后,再查一次 Redis 判斷是否在黑名單內(nèi)。
  • 注意:這只針對少數(shù)異常用戶,千萬不能對所有請求都查 Redis,否則失去無狀態(tài)的意義。

4. 生產(chǎn)級 Go 代碼架構(gòu)示例

為了讓你更清晰,給你一個 Go 項目的標準分層邏輯:

// 1. Access Token 中間件(只驗簽,不查庫)
func AuthMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        token := c.GetHeader("Authorization")
        // 只做本地解析和驗簽
        claims, err := jwt.ParseWithClaims(token, &MyClaims{}, func(t *jwt.Token) (interface{}, error) {
            return mySecret, nil
        })
        if err != nil || claims.ExpiresAt.Time.Before(time.Now()) {
            c.AbortWithStatusJSON(401, "token expired")
            return
        }
        // 極小概率查黑名單(只針對被拉黑的用戶)
        if redis.Exists(ctx, "blacklist:"+claims.Id).Val() > 0 {
            c.AbortWithStatusJSON(403, "revoked")
            return
        }
        c.Set("user_id", claims.UserID)
        c.Next()
    }
}
// 2. Refresh 接口(必須查庫)
func RefreshHandler(c *gin.Context) {
    refreshToken := c.GetHeader("X-Refresh-Token")
    // 步驟1:本地驗簽(防篡改)
    claims, err := jwt.ParseWithClaims(refreshToken, &MyClaims{}, ...)
    if err != nil {
        c.JSON(401, "invalid")
        return
    }
    // 步驟2:查數(shù)據(jù)庫(關(guān)鍵!)
    var dbRecord RefreshTokenModel
    db.Where("jti = ? AND revoked = ? AND expires_at > ?", claims.Id, false, time.Now()).First(&dbRecord)
    if dbRecord.ID == 0 {
        c.JSON(401, "refresh token invalid or expired")
        return
    }
    // 步驟3:輪換策略(防重放攻擊)
    // 標記舊記錄為已用
    db.Model(&dbRecord).Update("revoked", true)
    // 生成新的 Access Token 和 Refresh Token
    newAccess := generateAccessToken(dbRecord.UserID)
    newRefresh := generateRefreshToken(dbRecord.UserID) // 攜帶新的 jti
    // 插入新 Refresh Token 記錄
    db.Create(&RefreshTokenModel{JTI: newClaims.Id, UserID: dbRecord.UserID, ExpiresAt: ...})
    c.JSON(200, gin.H{
        "access_token":  newAccess,
        "refresh_token": newRefresh,
    })
}

5. 最終結(jié)論(面試/答辯標準答案)

Token 類型是否存表核心原因
Access Token高頻校驗,存表會導(dǎo)致嚴重性能瓶頸。依賴本地驗簽 + 短過期時間保證安全。
Refresh Token低頻刷新(幾分鐘一次)。為了可撤銷防重放攻擊設(shè)備管理,必須持久化狀態(tài)。

如果你的 Go 項目用的是 Redis 而不是 MySQL 存 Refresh Token,也完全沒問題,只要保證持久化(開啟 AOF/RDB)即可,性能更高且天然支持 TTL。

現(xiàn)在可以對照你的項目檢查一下:如果你們的 Access Token 也查了庫,那說明代碼有優(yōu)化空間;如果 Refresh Token 沒存庫,那說明存在嚴重安全隱患,建議盡快補齊。

到此這篇關(guān)于淺談go token需要存表嗎的文章就介紹到這了,更多相關(guān)go token存表內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言實現(xiàn)開發(fā)一個簡單的gRPC Demo

    Go語言實現(xiàn)開發(fā)一個簡單的gRPC Demo

    這篇文章主要為大家詳細介紹了如何利用Go語言實現(xiàn)開發(fā)一個簡單的gRPC Demo,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起了解一下
    2023-07-07
  • Go語言中一些不常見的命令參數(shù)詳解

    Go語言中一些不常見的命令參數(shù)詳解

    這篇文章主要給大家介紹了關(guān)于Go語言中一些不常見的命令參數(shù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • golang調(diào)用dll的接口三種方式小結(jié)

    golang調(diào)用dll的接口三種方式小結(jié)

    本文介紹了在Go語言中使用syscall包的不同方法加載DLL文件,包括NewLazyDLL、MustLoadDLL、LoadLibrary以及它們在調(diào)用函數(shù)和處理不同數(shù)據(jù)類型轉(zhuǎn)換中的應(yīng)用,感興趣的可以了解一下
    2025-07-07
  • 深入理解Golang中的Protocol Buffers及其應(yīng)用

    深入理解Golang中的Protocol Buffers及其應(yīng)用

    本篇文章將深入探討 Go 語言中使用 Protobuf 的基礎(chǔ)知識、常見應(yīng)用以及最佳實踐,希望能幫大家了解如何在項目中高效利用 Protobuf
    2024-11-11
  • 重學(xué)Go語言之如何使用Modules

    重學(xué)Go語言之如何使用Modules

    Go語言在Go.1.11版本發(fā)布了Go?Modules,這是一種新的Go項目依賴管理解決方案,可以讓Go項目的依賴包關(guān)系更加清晰,也更容易管理,下面就來看看Modules是如何使用的吧
    2023-07-07
  • go語言讀取json并下載高清妹子圖片

    go語言讀取json并下載高清妹子圖片

    前面我們介紹了使用python下載高清妹子圖,作為程序猿,我們當然不能只會一種語言,今天我們就來使用go語言來讀取API來下載妹子圖吧,有需要的宅男們可以參考下。
    2015-03-03
  • go中string、int、float相互轉(zhuǎn)換的實現(xiàn)示例

    go中string、int、float相互轉(zhuǎn)換的實現(xiàn)示例

    本文主要介紹了go中string、int、float相互轉(zhuǎn)換的實現(xiàn)示例,文中根據(jù)實例編碼詳細介紹的十分詳盡,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 使用client-go工具調(diào)用kubernetes API接口的教程詳解(v1.17版本)

    使用client-go工具調(diào)用kubernetes API接口的教程詳解(v1.17版本)

    這篇文章主要介紹了使用client-go工具調(diào)kubernetes API接口(v1.17版本),本文通過圖文實例相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • go Http Post 發(fā)送文件流案例

    go Http Post 發(fā)送文件流案例

    這篇文章主要介紹了go Http Post 發(fā)送文件流案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go批量操作excel導(dǎo)入到mongodb的技巧

    Go批量操作excel導(dǎo)入到mongodb的技巧

    這篇文章主要介紹了Go批量操作excel導(dǎo)入到mongo,包括選擇命令行包,讀取配置連接數(shù)據(jù)庫的方法,本文示例代碼相結(jié)合給大家介紹的非常詳細,需要的朋友可以參考下
    2022-03-03

最新評論

惠水县| 大名县| 枣庄市| 福海县| 隆昌县| 淮安市| 维西| 正宁县| 类乌齐县| 德阳市| 塘沽区| 都昌县| 徐州市| 乌恰县| 宜昌市| 寻乌县| 乳源| 大城县| 布尔津县| 长阳| 荔波县| 宁城县| 雅安市| 无为县| 安远县| 临猗县| 泾源县| 望奎县| 海阳市| 庆元县| 买车| 翁牛特旗| 建阳市| 罗城| 澜沧| 吉林市| 大姚县| 长兴县| 阿克陶县| 莱州市| 修文县|