Xác thực JSON Web Token (JWT) với Golang
Hướng dẫn cách sử dụng JSON Web Token (JWT) để xác thực người dùng trong ứng dụng Golang. Bài viết sẽ trình bày chi tiết cách tạo, ký và xác minh token JWT để bảo mật API.
Trong bài viết này, chúng ta sẽ tìm hiểu cách cài đặt và sử dụng JWT trong ứng dụng Golang. JWT là một tiêu chuẩn mở để truyền tải thông tin giữa các bên một cách an toàn. Chúng ta sẽ xây dựng một API đơn giản có khả năng xác thực người dùng bằng JWT.
Mã Golang:
package main
import (
"fmt"
"net/http"
"github.com/dgrijalva/jwt-go"
"time"
)
var mySigningKey = []byte("secret")
// Định nghĩa cấu trúc cho token
type Claims struct {
Username string `json:"username"`
jwt.StandardClaims
}
// Hàm tạo token
func CreateToken(username string) (string, error) {
expirationTime := time.Now().Add(5 * time.Minute)
claims := &Claims{
Username: username,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(mySigningKey)
}
// Hàm xác thực token
func ValidateToken(w http.ResponseWriter, r *http.Request) {
tokenString := r.Header.Get("Authorization")
if tokenString == "" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return mySigningKey, nil
})
if err != nil || !token.Valid {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
fmt.Fprintf(w, "Token is valid!")
}
// Hàm xử lý yêu cầu đăng nhập
func Login(w http.ResponseWriter, r *http.Request) {
username := r.URL.Query().Get("username")
token, err := CreateToken(username)
if err != nil {
http.Error(w, "Unable to create token", http.StatusInternalServerError)
return
}
w.Header().Set("Authorization", token)
fmt.Fprintf(w, "Token: %s", token)
}
func main() {
http.HandleFunc("/login", Login)
http.HandleFunc("/validate", ValidateToken)
fmt.Println("Server starting on :8080")
http.ListenAndServe(":8080", nil)
}
Giải thích chi tiết từng dòng code:
-
package main
: Định nghĩa gói chính của ứng dụng. -
import
: Nhập các gói cần thiết, bao gồmhttp
vàjwt-go
. -
var mySigningKey = []byte("secret")
: Khai báo khóa bí mật để ký token. -
type Claims struct {...}
: Định nghĩa cấu trúc Claims để lưu thông tin trong token. -
func CreateToken(username string)
: Hàm tạo token JWT. -
expirationTime := time.Now().Add(5 * time.Minute)
: Thiết lập thời gian hết hạn cho token. -
token := jwt.NewWithClaims(...)
: Tạo một token mới với các Claims đã định nghĩa. -
return token.SignedString(mySigningKey)
: Ký token và trả về chuỗi token. -
func ValidateToken(...)
: Hàm xác thực token từ header. -
token, err := jwt.Parse(...)
: Phân tích token từ chuỗi và kiểm tra tính hợp lệ. -
if err != nil || !token.Valid {...}
: Kiểm tra xem token có hợp lệ không. -
func Login(...)
: Hàm xử lý yêu cầu đăng nhập, tạo và trả về token cho người dùng. -
func main()
: Hàm chính, thiết lập các route cho server và khởi động server.
Yêu cầu hệ thống:
- Golang version: 1.15 trở lên.
- Thư viện
jwt-go
: có thể cài đặt bằng lệnhgo get github.com/dgrijalva/jwt-go
.
Cách cài đặt các thư viện để chạy được đoạn mã Golang trên:
Chạy lệnh sau trong terminal để cài đặt thư viện jwt-go
:
go get github.com/dgrijalva/jwt-go
Lời khuyên:
- Sử dụng khóa bí mật mạnh và bảo mật để ký token.
- Thời gian hết hạn của token nên được thiết lập hợp lý để đảm bảo bảo mật nhưng cũng không làm gián đoạn trải nghiệm người dùng.