GoDasturchi
Authentication: Token-Based Sessions

Authentication: Token-Based Sessions

Autentifikatsiya: Token asosidagi sessiyalar

Muhrlangan zarf tasavvur qiling: xat ICHIDAGI matnni O'ZGARTIRIB, muhrni ESKI holicha qoldirib bo'lmaydi — muhr FAQAT asl jo'natuvchida bor maxsus BOSQICH bilan qo'yiladi. Agar kimdir xatni O'ZGARTIRSA, muhr endi mos KELMAYDI. HMAC-imzolangan token — aynan shu g'oya: server foydalanuvchi nomini "maxfiy kalit" bilan IMZOLAYDI, va keyinchalik token qaytib kelganda, imzoni QAYTA hisoblab, MOSLIGINI tekshiradi — agar kimdir tokenni O'ZGARTIRGAN bo'lsa, imzo MOS KELMAYDI.

example.go
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"strings"
)

var secretKey = []byte("bookstore-super-secret-key")

// sign — payload'ning HMAC-SHA256 imzosini (hex satr sifatida) hisoblaydi
func sign(payload string) string {
	mac := hmac.New(sha256.New, secretKey)
	mac.Write([]byte(payload))
	return hex.EncodeToString(mac.Sum(nil))
}

// issueToken — "username.imzo" shaklidagi oddiy token yaratadi
func issueToken(username string) string {
	return username + "." + sign(username)
}

// verifyToken — token ICHIDAGI imzoni QAYTA hisoblab, mos kelishini tekshiradi
func verifyToken(token string) (username string, ok bool) {
	parts := strings.SplitN(token, ".", 2)
	if len(parts) != 2 {
		return "", false
	}
	username, sig := parts[0], parts[1]
	expected := sign(username)
	if hmac.Equal([]byte(sig), []byte(expected)) {
		return username, true
	}
	return "", false
}

func main() {
	token := issueToken("shohruh")
	fmt.Println(token)

	user, ok := verifyToken(token)
	fmt.Println(user, ok)

	tampered := "boshqa_user." + strings.SplitN(token, ".", 2)[1]
	user, ok = verifyToken(tampered)
	fmt.Println(user, ok)
}

hmac.New(sha256.New, secretKey) + mac.Write + mac.Sum(nil) — Go standart kutubxonasidagi HMAC hisoblash naqshi: secretKey FAQAT serverda saqlanadi, mijoz uni HECH QACHON bilmaydi. hmac.Equal (oddiy == EMAS!) ishlatiladi, chunki u "timing attack"ga qarshi, DOIMIY vaqtda solishtiradi — bu xavfsizlik kodida MUHIM detal.

tampered misolida: username "shohruh"dan "boshqa_user"ga O'ZGARTIRILDI, lekin IMZO (sig) ESKI holicha qoldi. verifyToken YANGI username uchun imzoni QAYTA hisoblaganda, u ESKI imzoga MOS KELMAYDI — shuning uchun false qaytadi. Bu — HMAC imzoning ASOSIY maqsadi: token TARKIBINI O'ZGARTIRISHNING IMKONI YO'Q, chunki secretKeysiz TO'G'RI imzo hisoblab BO'LMAYDI.

>_ Exercise

Tokenni HAQIQIY HTTP so'rov sarlavhasi orqali tekshiruvchi middleware yozing.

  • requireAuth(next func(w, r, username string)) http.HandlerFunc middleware'ini yozing: "Authorization" sarlavhasidan "Bearer " prefiksini olib tashlab, verifyToken chaqiring
  • token noto'g'ri/yo'q bo'lsa 401 va "avtorizatsiya talab qilinadi" matnini yozing
  • "GET /profile" endpoint'ini yozing: muvaffaqiyatli bo'lsa "salom, <username>" qaytarsin
  • TO'G'RI token, sarlavhasiz so'rov, va O'ZGARTIRILGAN (tampered) token bilan uchta so'rov yuborib, har birining status+tanasini chop eting

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

Token asosidagi autentifikatsiya — foydalanuvchi nomini maxfiy kalit bilan HMAC orqali imzolab, keyin har so'rovda imzoni QAYTA tekshiradi; bu — tokenni O'ZGARTIRISHNING iloji yo'qligini, standart kutubxona vositalari bilan kafolatlaydi.

NEXT UP

Authorization: Role-Based Access Control

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

Authentication: Token-Based Sessions

Autentifikatsiya: Token asosidagi sessiyalar

Muhrlangan zarf tasavvur qiling: xat ICHIDAGI matnni O'ZGARTIRIB, muhrni ESKI holicha qoldirib bo'lmaydi — muhr FAQAT asl jo'natuvchida bor maxsus BOSQICH bilan qo'yiladi. Agar kimdir xatni O'ZGARTIRSA, muhr endi mos KELMAYDI. HMAC-imzolangan token — aynan shu g'oya: server foydalanuvchi nomini "maxfiy kalit" bilan IMZOLAYDI, va keyinchalik token qaytib kelganda, imzoni QAYTA hisoblab, MOSLIGINI tekshiradi — agar kimdir tokenni O'ZGARTIRGAN bo'lsa, imzo MOS KELMAYDI.

example.go
package main

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"strings"
)

var secretKey = []byte("bookstore-super-secret-key")

// sign — payload'ning HMAC-SHA256 imzosini (hex satr sifatida) hisoblaydi
func sign(payload string) string {
	mac := hmac.New(sha256.New, secretKey)
	mac.Write([]byte(payload))
	return hex.EncodeToString(mac.Sum(nil))
}

// issueToken — "username.imzo" shaklidagi oddiy token yaratadi
func issueToken(username string) string {
	return username + "." + sign(username)
}

// verifyToken — token ICHIDAGI imzoni QAYTA hisoblab, mos kelishini tekshiradi
func verifyToken(token string) (username string, ok bool) {
	parts := strings.SplitN(token, ".", 2)
	if len(parts) != 2 {
		return "", false
	}
	username, sig := parts[0], parts[1]
	expected := sign(username)
	if hmac.Equal([]byte(sig), []byte(expected)) {
		return username, true
	}
	return "", false
}

func main() {
	token := issueToken("shohruh")
	fmt.Println(token)

	user, ok := verifyToken(token)
	fmt.Println(user, ok)

	tampered := "boshqa_user." + strings.SplitN(token, ".", 2)[1]
	user, ok = verifyToken(tampered)
	fmt.Println(user, ok)
}

hmac.New(sha256.New, secretKey) + mac.Write + mac.Sum(nil) — Go standart kutubxonasidagi HMAC hisoblash naqshi: secretKey FAQAT serverda saqlanadi, mijoz uni HECH QACHON bilmaydi. hmac.Equal (oddiy == EMAS!) ishlatiladi, chunki u "timing attack"ga qarshi, DOIMIY vaqtda solishtiradi — bu xavfsizlik kodida MUHIM detal.

tampered misolida: username "shohruh"dan "boshqa_user"ga O'ZGARTIRILDI, lekin IMZO (sig) ESKI holicha qoldi. verifyToken YANGI username uchun imzoni QAYTA hisoblaganda, u ESKI imzoga MOS KELMAYDI — shuning uchun false qaytadi. Bu — HMAC imzoning ASOSIY maqsadi: token TARKIBINI O'ZGARTIRISHNING IMKONI YO'Q, chunki secretKeysiz TO'G'RI imzo hisoblab BO'LMAYDI.

>_ Exercise

Tokenni HAQIQIY HTTP so'rov sarlavhasi orqali tekshiruvchi middleware yozing.

  • requireAuth(next func(w, r, username string)) http.HandlerFunc middleware'ini yozing: "Authorization" sarlavhasidan "Bearer " prefiksini olib tashlab, verifyToken chaqiring
  • token noto'g'ri/yo'q bo'lsa 401 va "avtorizatsiya talab qilinadi" matnini yozing
  • "GET /profile" endpoint'ini yozing: muvaffaqiyatli bo'lsa "salom, <username>" qaytarsin
  • TO'G'RI token, sarlavhasiz so'rov, va O'ZGARTIRILGAN (tampered) token bilan uchta so'rov yuborib, har birining status+tanasini chop eting

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

Token asosidagi autentifikatsiya — foydalanuvchi nomini maxfiy kalit bilan HMAC orqali imzolab, keyin har so'rovda imzoni QAYTA tekshiradi; bu — tokenni O'ZGARTIRISHNING iloji yo'qligini, standart kutubxona vositalari bilan kafolatlaydi.

NEXT UP

Authorization: Role-Based Access Control