GoDasturchi
Authentication: API Keys

Authentication: API Keys

Autentifikatsiya: API kalitlari

Mehmonxona resepshinida har bir MIJOZGA shaxsiy KARTOCHKA (keycard) beriladi. Xona eshigi oldida turgan xodim kartochkani KO'RADI, uni RO'YXATDAN o'tkazilgan kartochkalar bilan SOLISHTIRADI, va faqat mos kelsa KIRISHGA ruxsat beradi. API kalit (API key) autentifikatsiyasi — aynan shu naqsh: mijoz HAR BIR so'rovda maxsus "kartochka" (uzun, tasodifiy satr) yuboradi, server esa uni O'ZINING ro'yxati bilan solishtiradi.

example.go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
)

var apiKeys = map[string]string{
	"key-abc": "Acme Corp",
	"key-xyz": "Widget Inc",
}

type ErrorBody struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

type ErrorResponse struct {
	Error ErrorBody `json:"error"`
}

func writeError(w http.ResponseWriter, status int, code, message string) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	json.NewEncoder(w).Encode(ErrorResponse{Error: ErrorBody{Code: code, Message: message}})
}

// requireAPIKey — X-API-Key sarlavhasini tekshiradigan middleware
func requireAPIKey(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		key := r.Header.Get("X-API-Key")
		if key == "" {
			writeError(w, http.StatusUnauthorized, "missing_api_key", "X-API-Key sarlavhasi kerak")
			return
		}
		if _, ok := apiKeys[key]; !ok {
			writeError(w, http.StatusUnauthorized, "invalid_api_key", "API kalit noto'g'ri")
			return
		}
		next(w, r)
	}
}

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("GET /books", requireAPIKey(func(w http.ResponseWriter, r *http.Request) {
		client := apiKeys[r.Header.Get("X-API-Key")]
		fmt.Fprintf(w, "salom, %s", client)
	}))

	req1 := httptest.NewRequest("GET", "/books", nil)
	rec1 := httptest.NewRecorder()
	mux.ServeHTTP(rec1, req1)
	fmt.Println(rec1.Code)
	fmt.Print(rec1.Body.String())

	req2 := httptest.NewRequest("GET", "/books", nil)
	req2.Header.Set("X-API-Key", "key-abc")
	rec2 := httptest.NewRecorder()
	mux.ServeHTTP(rec2, req2)
	fmt.Println(rec2.Code)
	fmt.Println(rec2.Body.String())
}

requireAPIKey(next http.HandlerFunc) http.HandlerFuncmiddleware naqshi ("Middleware: Authentication" darsini eslang): u HAQIQIY handler'ni (next) O'RAB oladi, so'rov nextga YETISHDAN OLDIN tekshiruv o'tkazadi. Agar kalit YO'Q yoki NOTO'G'RI bo'lsa, next UMUMAN chaqirilmaydi — biznes mantiq HECH QACHON autentifikatsiyasiz so'rovni KO'RMAYDI.

Diqqat qiling: IKKI XIL 401 holati BIR-BIRIDAN ALOHIDA code bilan ajratilgan (missing_api_key va invalid_api_key) — bu mijozga (yoki uni YOZGAN dasturchiga) MUAMMONING aniq SABABINI ko'rsatadi: "kalitni UMUMAN yubormadingizmi" yoki "yuborgan kalitingiz NOTO'G'RImi" — bu "Error Message Style" darsidagi tamoyilning ANIQ qo'llanilishi.

>_ Exercise

NOTO'G'RI kalit holatini ham sinang.

  • send(mux, key string) (int, string) yordamchi funksiyasini yozing: key bo'sh bo'lmasa X-API-Key sarlavhasini o'rnatsin
  • send(mux, "") — kalit yo'q holatini sinang
  • send(mux, "key-wrong") — NOTO'G'RI kalit holatini sinang
  • send(mux, "key-xyz") — TO'G'RI kalit holatini sinang
  • uchala holatning ham status va tanasini chop eting

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

API kalit autentifikatsiyasi — middleware orqali HAR BIR so'rovda maxsus sarlavhani tekshiradi va tanib bo'lmagan yoki yo'q kalitni ANIQ, ALOHIDA xato kodlari bilan rad etadi, biznes mantiqni FAQAT tasdiqlangan so'rovlarga OCHIQ qoldiradi.

NEXT UP

Authentication: Token-Based Sessions

OUTPUT

$ go run main.go
Kodingizni ishga tushiring

Authentication: API Keys

Autentifikatsiya: API kalitlari

Mehmonxona resepshinida har bir MIJOZGA shaxsiy KARTOCHKA (keycard) beriladi. Xona eshigi oldida turgan xodim kartochkani KO'RADI, uni RO'YXATDAN o'tkazilgan kartochkalar bilan SOLISHTIRADI, va faqat mos kelsa KIRISHGA ruxsat beradi. API kalit (API key) autentifikatsiyasi — aynan shu naqsh: mijoz HAR BIR so'rovda maxsus "kartochka" (uzun, tasodifiy satr) yuboradi, server esa uni O'ZINING ro'yxati bilan solishtiradi.

example.go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
)

var apiKeys = map[string]string{
	"key-abc": "Acme Corp",
	"key-xyz": "Widget Inc",
}

type ErrorBody struct {
	Code    string `json:"code"`
	Message string `json:"message"`
}

type ErrorResponse struct {
	Error ErrorBody `json:"error"`
}

func writeError(w http.ResponseWriter, status int, code, message string) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	json.NewEncoder(w).Encode(ErrorResponse{Error: ErrorBody{Code: code, Message: message}})
}

// requireAPIKey — X-API-Key sarlavhasini tekshiradigan middleware
func requireAPIKey(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		key := r.Header.Get("X-API-Key")
		if key == "" {
			writeError(w, http.StatusUnauthorized, "missing_api_key", "X-API-Key sarlavhasi kerak")
			return
		}
		if _, ok := apiKeys[key]; !ok {
			writeError(w, http.StatusUnauthorized, "invalid_api_key", "API kalit noto'g'ri")
			return
		}
		next(w, r)
	}
}

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc("GET /books", requireAPIKey(func(w http.ResponseWriter, r *http.Request) {
		client := apiKeys[r.Header.Get("X-API-Key")]
		fmt.Fprintf(w, "salom, %s", client)
	}))

	req1 := httptest.NewRequest("GET", "/books", nil)
	rec1 := httptest.NewRecorder()
	mux.ServeHTTP(rec1, req1)
	fmt.Println(rec1.Code)
	fmt.Print(rec1.Body.String())

	req2 := httptest.NewRequest("GET", "/books", nil)
	req2.Header.Set("X-API-Key", "key-abc")
	rec2 := httptest.NewRecorder()
	mux.ServeHTTP(rec2, req2)
	fmt.Println(rec2.Code)
	fmt.Println(rec2.Body.String())
}

requireAPIKey(next http.HandlerFunc) http.HandlerFuncmiddleware naqshi ("Middleware: Authentication" darsini eslang): u HAQIQIY handler'ni (next) O'RAB oladi, so'rov nextga YETISHDAN OLDIN tekshiruv o'tkazadi. Agar kalit YO'Q yoki NOTO'G'RI bo'lsa, next UMUMAN chaqirilmaydi — biznes mantiq HECH QACHON autentifikatsiyasiz so'rovni KO'RMAYDI.

Diqqat qiling: IKKI XIL 401 holati BIR-BIRIDAN ALOHIDA code bilan ajratilgan (missing_api_key va invalid_api_key) — bu mijozga (yoki uni YOZGAN dasturchiga) MUAMMONING aniq SABABINI ko'rsatadi: "kalitni UMUMAN yubormadingizmi" yoki "yuborgan kalitingiz NOTO'G'RImi" — bu "Error Message Style" darsidagi tamoyilning ANIQ qo'llanilishi.

>_ Exercise

NOTO'G'RI kalit holatini ham sinang.

  • send(mux, key string) (int, string) yordamchi funksiyasini yozing: key bo'sh bo'lmasa X-API-Key sarlavhasini o'rnatsin
  • send(mux, "") — kalit yo'q holatini sinang
  • send(mux, "key-wrong") — NOTO'G'RI kalit holatini sinang
  • send(mux, "key-xyz") — TO'G'RI kalit holatini sinang
  • uchala holatning ham status va tanasini chop eting

Stuck? Reveal a hint to help you.

Hints (0/3)

Key Takeaway

Key Takeaway:

API kalit autentifikatsiyasi — middleware orqali HAR BIR so'rovda maxsus sarlavhani tekshiradi va tanib bo'lmagan yoki yo'q kalitni ANIQ, ALOHIDA xato kodlari bilan rad etadi, biznes mantiqni FAQAT tasdiqlangan so'rovlarga OCHIQ qoldiradi.

NEXT UP

Authentication: Token-Based Sessions