Golang İle Jwt Token Üretmek

Abdulkerim Karaman
alBarakaTech Global
3 min readNov 14, 2021

Json Web Token, Json tabanlı RFC 7519 ‘de tanımlanmış açık bir standarttır. Bir çok programlama dilinde, uygulamaların birbirleri arasında güvenli veri alışverişini sağlamak için JWT (Json Web Token) kullanılmaktadır. Bunun yanında uygulamalarda authentication (kullanıcı doğrulama) işlemlerinde de sıkça kullanılmaktadır.

JWT kendi içinde üç kısma ayrılmaktadır.

Header:

Header kısmında crytographic hash algoritmasını ve tipini içerir.

{ 
"alg" : "HS256",
"typ" : "JWT"
}

Payload:

İstemci ve sunucu arasındaki claim dataları ifade eder. Claim; Sunucu tarafından doğrulanmış kullanıcılara ait bilgilerin tutulduğu alandır. Payload kısmında hassas veriler taşınmamalıdır. Payload üzerinde registered claims, public claims, private claims olmak üzere üç çeşit claims tipi vardır. Daha detaylı bilgilere aşağıdaki linkten ulaşabilirsiniz.

https://datatracker.ietf.org/doc/html/rfc7519#section-4

Signature (imza):

Bu kısım base64UrlEncode ile encode edilmiş header ve payload bilgilerinden oluşur. Buradaki veriler ile beraber bir imzalama işlemi yapılarak jwt ‘nin sonuna eklenir.

HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)

Golang dilinde JWT entegrasyonu için en çok kullanılan kütüphanelerden biri de açık kaynak olarak sunulan golang-jwt ‘dir.

Yeni bir go web api projesi üzerinde ilgili golang-jwt kullanarak bir örnek yapalım.

Boş bir klasör içinde main.go dosyası oluşturarak golang-jwt paketimizi import edelim. Ayrıca mux paketini de routing için ekliyelim.

import (
"github.com/dgrijalva/jwt-go"
"github.com/gorilla/mux"
)

Öncelikle Claims struct ‘ımızı oluşturalım. JWT Claims (Payload) kısmında username bilgisini tutacağımızı varsayarak modelimize bu alanı ekliyoruz.

type Claims struct {
Username string `json:"username"`
jwt.StandardClaims
}

Şimdi token’ı üretecek methodumuzu yazabiliriz.

my_secret_key alanına jwt token üretmek için kullanacağımız key bilgisini girebilirsiniz. Ben örnek olması açısından bu değeri yazıyorum.

expirationTime := time.Now().Add(5 * time.Minute)
var jwtKey = []byte("my_secret_key")
claims := &Claims{
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(),
},
}

Şimdi ilgili claims’i kullanarak bir token üretebiliriz. Burada dikkat ederseniz NewWithClaims methodunun ilk parametresine jwt.SigningMethodHS256 ekleyerek şifrelemek için kullanacağımız HMAC algoritmasını belirtiyoruz.

token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

tokenString, err := token.SignedString(jwtKey)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}

token.SignedString(jwtKey) methoduna key’imizi göndererek imzalanmış token değerini elde edebiliriz.

Aşağıdaki kod ile apinin response’una ilgili token değerimizi ekleyelim.

fmt.Fprintf(w, tokenString)

Uygulamamızın son hali aşağıdaki gibidir.

Main.go

package mainimport (
"fmt"
"log"
"net/http"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/gorilla/mux"
)
type Claims struct {
Username string `json:"username"`
jwt.StandardClaims
}
func getToken(w http.ResponseWriter, r *http.Request) {
expirationTime := time.Now().Add(5 * time.Minute)
var jwtKey = []byte("my_secret_key")
claims := &Claims{
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(),
},
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

tokenString, err := token.SignedString(jwtKey)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
fmt.Fprintf(w, tokenString)
}
func main() {
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/token", getToken).Methods("GET")
log.Fatal(http.ListenAndServe(":8080", router))
}

Main dosyamızı çalıştırarak localhost:8080/token adresine http get yaparak sonucu görelim.

go run main.go

Evet uygulama başarılı bir şekilde token üreterek response üretti.

Bir sonraki yazımızda görüşmek dileğiyle. Hoşça kalın..

--

--