Go語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單JWT登錄驗(yàn)證的示例代碼
在 Web 開(kāi)發(fā)中,身份驗(yàn)證是一個(gè)繞不開(kāi)的話題。傳統(tǒng)的 Session 機(jī)制依賴服務(wù)器存儲(chǔ)用戶狀態(tài),而在微服務(wù)、分布式架構(gòu)下,這種方式可能會(huì)導(dǎo)致?tīng)顟B(tài)同步困難。
JWT(JSON Web Token)是一種無(wú)狀態(tài)的、跨平臺(tái)的身份驗(yàn)證解決方案,非常適合現(xiàn)代 Web API 場(chǎng)景。
本文將帶你用 Go 實(shí)現(xiàn)一個(gè) JWT 登錄驗(yàn)證示例,掌握它的基本原理與使用方式。
一、什么是 JWT
JWT 的結(jié)構(gòu)由三部分組成:
header.payload.signature
- • Header:聲明類型(JWT)和加密算法(如 HMAC SHA256)。
- • Payload:存放業(yè)務(wù)數(shù)據(jù)(如用戶ID、角色、過(guò)期時(shí)間)。
- • Signature:對(duì)前兩部分進(jìn)行簽名,保證數(shù)據(jù)不可篡改。
例如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJ1c2VyX2lkIjoxLCJleHAiOjE3MDAwMDAwMDB9
.abc123456789xyz
二、實(shí)現(xiàn)思路
1. 用戶登錄 → 校驗(yàn)賬號(hào)密碼正確 → 生成 JWT 返回給前端。
2. 前端請(qǐng)求 API → 在 Authorization 頭中攜帶 JWT。
3. 后端中間件 → 解析 JWT,驗(yàn)證有效性與過(guò)期時(shí)間。
4. 通過(guò)驗(yàn)證 → 執(zhí)行后續(xù)業(yè)務(wù)邏輯。
三、代碼實(shí)現(xiàn)
我們使用 github.com/golang-jwt/jwt/v5 作為 JWT 庫(kù)。
1. 初始化依賴
go get github.com/golang-jwt/jwt/v5
2. 定義 JWT 工具
package main
import (
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
)
var jwtSecret = []byte("my_secret_key")
// 生成Token
func GenerateToken(username string) (string, error) {
claims := jwt.MapClaims{
"username": username,
"exp": time.Now().Add(2 * time.Hour).Unix(),
"iat": time.Now().Unix(),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(jwtSecret)
}
// 驗(yàn)證Token
func ParseToken(tokenString string) (jwt.MapClaims, error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return jwtSecret, nil
})
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
return claims, nil
}
return nil, err
}
3. 構(gòu)建簡(jiǎn)單登錄和受保護(hù)接口
package main
import (
"encoding/json"
"fmt"
"net/http"
"strings"
)
// 模擬用戶數(shù)據(jù)
var users = map[string]string{
"alice": "123456",
"bob": "654321",
}
func loginHandler(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("username")
password := r.FormValue("password")
if pwd, ok := users[username]; !ok || pwd != password {
http.Error(w, "用戶名或密碼錯(cuò)誤", http.StatusUnauthorized)
return
}
token, _ := GenerateToken(username)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"token": token})
}
func authMiddleware(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
http.Error(w, "缺少Authorization頭", http.StatusUnauthorized)
return
}
parts := strings.SplitN(authHeader, " ", 2)
if len(parts) != 2 || parts[0] != "Bearer" {
http.Error(w, "Authorization格式錯(cuò)誤", http.StatusUnauthorized)
return
}
claims, err := ParseToken(parts[1])
if err != nil {
http.Error(w, "無(wú)效Token", http.StatusUnauthorized)
return
}
fmt.Printf("JWT解析結(jié)果: %+v\n", claims)
next.ServeHTTP(w, r)
}
}
func protectedHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "歡迎訪問(wèn)受保護(hù)的資源!")
}
func main() {
http.HandleFunc("/login", loginHandler)
http.HandleFunc("/protected", authMiddleware(protectedHandler))
fmt.Println("服務(wù)器啟動(dòng):http://localhost:8080")
http.ListenAndServe(":8080", nil)
}
4. 測(cè)試流程
1. 登錄獲取 Token
curl -X POST "http://localhost:8080/login" -d "username=alice&password=123456"
返回:
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI..."}
2. 訪問(wèn)受保護(hù)接口
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI..." http://localhost:8080/protected
輸出:
歡迎訪問(wèn)受保護(hù)的資源!
四、注意事項(xiàng)
1. Token 過(guò)期處理:前端需在過(guò)期后重新獲取 Token。
2. Secret 安全性:切勿將 jwtSecret 寫(xiě)死在代碼里,可用環(huán)境變量管理。
3. HTTPS:避免 Token 在明文傳輸中被竊取。
4. 黑名單機(jī)制:如果需要即時(shí)讓某個(gè) Token 失效,可以維護(hù)一個(gè)黑名單。
五、總結(jié)
JWT 在 Go 中實(shí)現(xiàn)并不復(fù)雜,但它帶來(lái)的無(wú)狀態(tài)身份驗(yàn)證機(jī)制,非常適合 RESTful API 和分布式架構(gòu)場(chǎng)景。
通過(guò)本示例,你可以快速搭建一個(gè)基于 JWT 的登錄驗(yàn)證系統(tǒng),并根據(jù)業(yè)務(wù)需求進(jìn)行擴(kuò)展,比如刷新 Token、角色權(quán)限控制等。
到此這篇關(guān)于Go語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單JWT登錄驗(yàn)證的示例代碼的文章就介紹到這了,更多相關(guān)Go JWT登錄驗(yàn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語(yǔ)言基本的語(yǔ)法和內(nèi)置數(shù)據(jù)類型初探
這篇文章主要介紹了Go語(yǔ)言基本的語(yǔ)法和內(nèi)置數(shù)據(jù)類型,是golang入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-10-10
go語(yǔ)言通過(guò)odbc訪問(wèn)Sql Server數(shù)據(jù)庫(kù)的方法
這篇文章主要介紹了go語(yǔ)言通過(guò)odbc訪問(wèn)Sql Server數(shù)據(jù)庫(kù)的方法,實(shí)例分析了Go語(yǔ)言通過(guò)odbc連接與查SQL Server詢數(shù)據(jù)庫(kù)的技巧,需要的朋友可以參考下2015-03-03
Golang并發(fā)編程中Context包的使用與并發(fā)控制
Golang的context包提供了在并發(fā)編程中傳遞取消信號(hào)、超時(shí)控制和元數(shù)據(jù)的功能,本文就來(lái)介紹一下Golang并發(fā)編程中Context包的使用與并發(fā)控制,感興趣的可以了解一下2024-11-11
看看你的Go應(yīng)用是否用了正確CPU核數(shù)
這篇文章主要為大家介紹了Go應(yīng)用正確的CPU核數(shù)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06

