Go基礎(Gin)

go mod init my-gin-app?初始化一個 Go 項目,創建一個go.mod文件

go mod tidy? ? ? ? ? ? ? ? ? ?自動整理項目依賴,確保go.modgo.sum文件與代碼實際使用的依賴一致

  • go mod init:創建項目的 “依賴說明書”。
  • go mod tidy:整理 “說明書”,讓依賴清單精確匹配代碼。

代碼基礎

package mainimport "github.com/gin-gonic/gin"func main() {// 創建默認引擎,包含日志和恢復中間件r := gin.Default()// 定義根路徑的 GET 請求r.GET("/", func(c *gin.Context) {c.JSON(200, gin.H{"message": "Hello World",})})// 啟動服務器,監聽 8080 端口r.Run() // 默認監聽 :8080
}

參數查詢代碼

package mainimport "github.com/gin-gonic/gin"func main() {// 創建默認引擎,包含日志和恢復中間件r := gin.Default()// 處理帶參數的 URL:/users/123r.GET("/users/:id", func(c *gin.Context) {id := c.Param("id")c.JSON(200, gin.H{"user_id": id,})})// 啟動服務器,監聽 8080 端口r.Run() // 默認監聽 :8080
}

處理 POST 請求并驗證賬號密碼

package mainimport "github.com/gin-gonic/gin"func main() {r := gin.Default()// 處理 POST 請求,驗證賬號密碼r.POST("/login", func(c *gin.Context) {// 定義請求體結構type LoginRequest struct {Username string `json:"username" binding:"required"`Password string `json:"password" binding:"required"`}var req LoginRequest// 綁定 JSON 請求體并驗證if err := c.ShouldBindJSON(&req); err != nil {c.JSON(400, gin.H{"error": err.Error()})return}// 驗證賬號密碼if req.Username == "123" && req.Password == "123" {c.JSON(200, gin.H{"message": "驗證正確"})} else {c.JSON(401, gin.H{"message": "賬號或密碼錯誤"})}})r.Run()
}
  • json:"password"?就是這個「翻譯器」。
  • 當你收到一個 JSON 數據(比如?{"password": "123"}),Gin 會自動把 JSON 里的?password?字段,對應到 Go 代碼里的?Password?變量。
  • binding:"required"?表示這個字段「必須存在」,如果 JSON 里沒有這個字段,就會報錯。

ShouldBindJSON?會做兩件事

  1. 翻譯:把 JSON 里的字段名(比如?password),對應到 Go 結構體的變量(比如?Password)。
  2. 檢查規則:檢查每個字段是否符合?binding:"required"?等規則。

JWT

package mainimport ("github.com/dgrijalva/jwt-go""github.com/gin-gonic/gin""net/http""time"
)// 密鑰(生產環境應從配置文件或環境變量獲取)
var jwtKey = []byte("your-secret-key")// Token中包含的用戶信息
type Claims struct {Username string `json:"username"`jwt.StandardClaims
}// 生成JWT Token
func generateToken(username string) (string, error) {expirationTime := time.Now().Add(1 * time.Hour)claims := &Claims{Username: username,StandardClaims: jwt.StandardClaims{ExpiresAt: expirationTime.Unix(),IssuedAt:  time.Now().Unix(),Issuer:    "your-app",},}token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)return token.SignedString(jwtKey)
}// 驗證JWT Token
func validateToken(tokenStr string) (*Claims, error) {claims := &Claims{}token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {return jwtKey, nil})if err != nil || !token.Valid {return nil, err}return claims, nil
}// 登錄接口 - 驗證用戶并生成Token
func loginHandler(c *gin.Context) {type LoginRequest struct {Username string `json:"username" binding:"required"`Password string `json:"password" binding:"required"`}var req LoginRequestif err := c.ShouldBindJSON(&req); err != nil {c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})return}if req.Username != "admin" || req.Password != "password" {c.JSON(http.StatusUnauthorized, gin.H{"error": "無效的憑證"})return}token, err := generateToken(req.Username)if err != nil {c.JSON(http.StatusInternalServerError, gin.H{"error": "生成Token失敗"})return}c.JSON(http.StatusOK, gin.H{"token": token,})
}// 認證中間件 - 檢查請求中的Token
func authMiddleware() gin.HandlerFunc {return func(c *gin.Context) {tokenStr := c.GetHeader("Authorization")if tokenStr == "" || len(tokenStr) < 7 || tokenStr[:7] != "Bearer " {c.JSON(http.StatusUnauthorized, gin.H{"error": "缺少或格式錯誤的Token"})c.Abort()return}tokenStr = tokenStr[7:]claims, err := validateToken(tokenStr)if err != nil {c.JSON(http.StatusUnauthorized, gin.H{"error": "無效的Token"})c.Abort()return}c.Set("username", claims.Username)c.Next()}
}// 受保護的接口 - 需要有效的Token才能訪問
func protectedHandler(c *gin.Context) {username := c.MustGet("username").(string)c.JSON(http.StatusOK, gin.H{"message": "歡迎回來," + username,"data":    "這是受保護的數據",})
}func main() {r := gin.Default()r.POST("/login", loginHandler)authGroup := r.Group("/api")authGroup.Use(authMiddleware()){authGroup.GET("/protected", protectedHandler)}r.Run()
}

Apipost測試

curl -X POST http://localhost:8080/login \-H "Content-Type: application/json" \-d '{"username": "admin", "password": "password"}'

響應

{"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNjk5OTk5OTk5LCJpYXQiOjE2OTk5OTk2OTksImlzcyI6InlvdXItYXBwIn0.abcdefghijklmnopqrstuvwxyz123456"
}
然后
curl -X GET http://localhost:8080/api/protected \-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

var jwtKey = []byte("your-secret-key")??your-secret-key?可以隨便寫嗎?

? 開發測試時:可以寫簡單的,但要注意
? 正式環境:必須用復雜、安全的密碼
    • 比如用?your-secret-key?或?123456,方便測試代碼是否正常運行。
    • 但千萬不要在正式環境用這種簡單密碼!就像日記本用 “123456” 當密碼,很容易被別人破解。
    • 規則
      • 長度至少 16 位,包含字母、數字、特殊符號(比如?!@#$%^&*())。
      • 不能是任何人都能猜到的內容(比如生日、名字)。

在 JWT 驗證流程中,用密鑰 “解鎖” Token?的核心代碼是?jwt.ParseWithClaims?函數。這個函數會驗證 Token 的簽名,并解析出其中的內容(Claims)。

// 定義Claims結構體用于存儲解析結果
claims := &Claims{}// 用密鑰"解鎖"Token(驗證簽名并解析內容)
token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {return jwtKey, nil  // 返回密鑰,用于驗證簽名
})

以下代碼模擬了一個被篡改的 Token 的驗證過程:

package mainimport ("fmt""github.com/dgrijalva/jwt-go"
)var jwtKey = []byte("your-secret-key")func main() {// 1. 生成一個合法的Tokenclaims := jwt.MapClaims{"username": "alice","exp":      jwt.TimeFunc().Add(time.Hour * 24).Unix(), // 24小時后過期}token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)tokenStr, _ := token.SignedString(jwtKey)fmt.Println("原始Token:", tokenStr)// 2. 模擬篡改Token(修改Payload中的username)// 注意:實際中無法直接修改,這里僅為演示驗證失敗的效果tamperedTokenStr := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImJvYiIsImV4cCI6MTY5OTQwNjQwMH0.abc123" // 偽造的Token// 3. 驗證原始Token(正常情況)validToken, validErr := jwt.ParseWithClaims(tokenStr, jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) {return jwtKey, nil})fmt.Println("原始Token驗證結果:", validToken.Valid, validErr)// 4. 驗證篡改后的TokentamperedToken, tamperedErr := jwt.ParseWithClaims(tamperedTokenStr, jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) {return jwtKey, nil})fmt.Println("篡改Token驗證結果:", tamperedToken.Valid, tamperedErr)
}

輸出結果

原始Token驗證結果: true <nil>
篡改Token驗證結果: false signature is invalid

從 Token 中獲取 username 的核心代碼

1. 定義 Claims 結構體

首先需要定義一個結構體,用于存儲 Token 中的數據:

type Claims struct {Username string `json:"username"`  // 對應Token中的username字段jwt.StandardClaims                  // 包含標準字段(如過期時間、簽發者等)
}
2. 驗證并解析 Token
// 驗證Token并獲取Claims
claims, err := validateToken(tokenStr)
if err != nil {// 處理驗證失敗的情況log.Fatal("Token驗證失敗:", err)
}// 從Claims中獲取username
username := claims.Username
fmt.Println("用戶名:", username)
3. 完整的驗證函數示例
func validateToken(tokenStr string) (*Claims, error) {claims := &Claims{}token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {// 驗證簽名方法if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {return nil, fmt.Errorf("無效的簽名方法: %v", token.Header["alg"])}// 返回密鑰return jwtKey, nil})// 檢查驗證錯誤if err != nil {return nil, err}// 檢查Token有效性if !token.Valid {return nil, errors.New("無效的Token")}return claims, nil
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/87363.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/87363.shtml
英文地址,請注明出處:http://en.pswp.cn/web/87363.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

21、鴻蒙學習——使用App Linking實現應用間跳轉

簡介 使用App Linking進行跳轉時&#xff0c;系統會根據接口傳入的uri信息&#xff08;HTTPS鏈接&#xff09;將用戶引導至目標應用中的特定內容&#xff0c;無論應用是否已安裝&#xff0c;用戶都可以訪問到鏈接對應的內容&#xff0c;跳轉體驗相比Deep Linking方式更加順暢。…

Cursor無限郵箱續費方法

1.注冊無限郵箱2925 2.“其他郵箱” 3.點擊左下角添加郵箱 4.管理員身份運行Windos PowerShell 5.輸入該指令并運行&#xff0c;修改機器碼 irm https://aizaozao.com/accelerate.php/https://raw.githubusercontent.com/yuaotian/go-cursor-help/refs/heads/master/scripts/…

LeetCode Hot100(圖論)

200. 島嶼數量 題意 給你一個由 1&#xff08;陸地&#xff09;和 0&#xff08;水&#xff09;組成的的二維網格&#xff0c;請你計算網格中島嶼的數量。 島嶼總是被水包圍&#xff0c;并且每座島嶼只能由水平方向和/或豎直方向上相鄰的陸地連接形成。 此外&#xff0c;你…

Ubuntu Gnome 安裝和卸載 WhiteSur-gtk-theme 類 Mac 主題的正確方法

WhiteSur-gtk-theme 是一個流行的 GNOME 桌面主題&#xff0c;可以讓 Ubuntu 的桌面環境看起來像 macOS。以下是安裝和卸載 WhiteSur-gtk-theme 的詳細步驟&#xff0c;包括解釋每個命令的作用。 一、安裝 WhiteSur-gtk-theme 1. 準備工作 在安裝主題之前&#xff0c;建議確…

如何在DataGear 5.4.1 中快速制作SQL服務端分頁的數據表格看板

DataGear 數據可視化分析平臺&#xff08;http://datagear.tech/&#xff09; 在新發布的5.4.1版本中&#xff0c;內置表格圖表新增了serverSidePaging選項&#xff0c;僅需通過簡單的配置&#xff0c;即可為表格添加服務端分頁、關鍵字查詢、排序功能。 本文以SQL數據集作為數…

股指期貨套保比例怎么算?

在金融市場里&#xff0c;套期保值&#xff08;套保&#xff09;是一種常見的風險管理手段&#xff0c;目的是通過期貨市場對沖現貨市場的風險。而套保比例&#xff08;也叫套保比率&#xff09;的計算&#xff0c;是套保操作的核心。簡單來說&#xff0c;套保比例就是“期貨頭…

邏輯回歸(Logistic Regression)算法詳解

文章目錄 一、邏輯回歸&#xff1a;從線性回歸到二分類的跨越1.1 邏輯回歸簡介1.2 Sigmoid函數&#xff1a;概率映射的數學本質1.3 參數 w w w 和 b b b 對Sigmoid的調控1.4 從線性回歸到分類1.5 決策邊界&#xff1a;從概率到類別&#xff08;結合圖3、圖4&#xff09; 二、…

HTTPS通信流程:SSL/TLS握手全解析

2021&#xff0c;2022&#xff0c;2023年1-8月看了很多技術書籍&#xff0c;現在想來忘了很多&#xff0c;用到的也不多&#xff0c;但是因為提前接觸過&#xff0c;所以很多新東西&#xff0c;接受起來&#xff0c;比預想的要容易些。最近突然想要回憶下HTTPS&#xff0c;居然…

SVG 在 VSCode 中的使用與優勢

SVG 在 VSCode 中的使用與優勢 引言 SVG(可縮放矢量圖形)是一種基于可擴展標記語言的圖形圖像格式,與傳統的位圖格式(如 JPEG 或 PNG)相比,SVG 圖像具有更高的靈活性和可縮放性。隨著前端開發領域的不斷發展,SVG 在網頁設計中的應用越來越廣泛。本文將介紹 SVG 在 Vis…

Ubuntu開放mysql 3306端口

Ubuntu開放mysql 3306端口 1. 檢查 UFW 防火墻規則2. 檢查 iptables 規則 1. 檢查 UFW 防火墻規則 sudo ufw status verbose | grep 3306若輸出包含 3306/tcp ALLOW&#xff0c;表示端口已開放(如下) ubuntuUbuntu2404:~$ sudo ufw status verbose | grep 3306 3306/tcp …

CentOS 卸載docker

1、停止docker服務 systemctl stop docker.socket systemctl stop docker systemctl stop containerd 2、列出已安裝的docker包 yum list installed | grep -i docker 輸出如下&#xff1a; containerd.io.x86_64 1.6.33-3.1.el7 docker-ce-stab…

MySQL數據庫----DML語句

目錄 DML-介紹SQL-DML-添加數據SQL-DML-修改數據SQL-DML-刪除數據 DML-介紹 DML英文全稱是 Data Manipulation Language(數據操作語言)&#xff0c;用來對數據庫中表的數據記錄進行增刪改操作。 添加數據&#xff08;INSERT&#xff09; 修改數據&#xff08;UPDATE&#xff…

Prompt:提示詞工程

前言在LLM大放異彩的今天&#xff0c;一個簡單的問題&#xff0c;可能就會引出一個方案&#xff0c;一篇散文&#xff0c;而驅動這一切的&#xff0c;正是輸入的“提示詞&#xff08;Prompt&#xff09;”Prompt工程就是&#xff1a;與大模型打交道時&#xff0c;如何更好地設計…

GSAP 動畫庫在 Vue3 項目中的使用總結

前言 GSAP&#xff08;GreenSock Animation Platform&#xff09;是目前最強大的 JavaScript 動畫庫之一&#xff0c;以其出色的性能和簡潔的API而聞名。本文將基于實際項目經驗&#xff0c;詳細介紹如何在 Vue3 項目中使用 GSAP 創建流暢、專業的動畫效果&#xff0c;包括核心…

【字節跳動】數據挖掘面試題0007:Kmeans原理,何時停止迭代

文章大綱 K-means 原理與迭代停止條件?? 一、K-Means核心思想&#x1f501; 二、迭代步驟詳解關鍵數學操作 ?? 三、何時停止迭代&#xff1f;Kmeans 算法實現代碼 ?? 四、面試常見擴展問題1. K值如何選擇&#xff1f;2. 初始質心影響結果嗎&#xff1f;3. 算法缺陷與改進…

209、長度最小的子數組

題目&#xff1a; 解答&#xff1a; 滑動窗口&#xff0c;左右指針指向窗口兩端&#xff0c;窗口為[left,right]&#xff0c;leftright時窗口只包含一個元素。 窗口內元素和sum>target時&#xff0c;left,推出左側一個元素;sum<target時&#xff0c;right&#xff0c;加…

關機精靈——自動化與便利性

文章目錄 背景目標實現下載 背景 自動化與便利性&#xff1a; 讓電腦在用戶無需值守或干預的情況下&#xff0c;在特定時間點&#xff08;倒計時結束&#xff09;或任務完成后自動關閉。節能與環保&#xff1a; 避免電腦在完成工作后或無人使用時繼續空耗電力。時間管理與健康…

L2CAP協議詳解:分段重組、QoS控制與多協議復用設計(面試寶典)

本文系統解析L2CAP協議的知識圖譜&#xff0c;掌握面試核心考點&#xff0c;并通過真題演練提升實戰能力。建議配合協議分析工具進行抓包實踐&#xff0c;加深對協議機制的理解。 一、L2CAP 在藍牙協議棧中的核心定位 L2CAP&#xff08;Logical Link Control and Adaptation P…

微軟服務器安全問題

微軟云服務器安全深度解析&#xff1a;挑戰、應對與未來展望——構建韌性“安全之盾”的持續博弈&#xff01; 在當今數字化時代&#xff0c;云計算已成為眾多企業和組織運行業務的核心基礎設施和“數字生命線”&#xff0c;而微軟云&#xff08;Azure&#xff09;作為全球領先…

后臺管理系統的誕生 - 利用AI 1天完成整個后臺管理系統的微服務后端+前端

AI創作系列(11)&#xff1a;后臺管理系統的誕生 - 利用AI 1天完成整個后臺管理系統的微服務后端前端 真實記錄&#xff1a;我決定為海貍IM添加一個后臺管理系統。從早上開始&#xff0c;到晚上結束&#xff0c;僅僅1天時間&#xff0c;我就完成了整個后臺管理系統的微服務后端和…