Go API'sini koruyun
Bu hızlı başlangıç, bir Go net/http API'sini KeenAuth erişim belirteçleriyle korur. Go SDK'nın protect ara katmanını eklersiniz, bir rotada bir kapsam zorunlu kılarsınız ve API'yi SDK test kiti ile çevrimdışı test edersiniz. Ara katman yalnızca standart kütüphaneyi kullanır ve bir http.Handler kabul eden her yönlendiriciyle çalışır.
API'nin üç uç noktası vardır:
| Uç nokta | Gerektirir |
|---|---|
GET /api/public |
hiçbir şey |
GET /api/private |
API'niz için geçerli bir erişim belirteci |
GET /api/messages |
messages:read kapsamına sahip geçerli bir erişim belirteci |
Başlamadan önce
- Bir KeenAuth ortamı. Veren adresi
https://your-environment.eu.keenauth.appbiçimindedir. - Ortamda kayıtlı bir API (API oluşturun). Onun
identifierdeğeri, örneğinhttps://api.example.com, API'nizin kabul ettiği belirteçlerin hedef kitlesidir. - Bu API üzerinde, onu çağıran uygulamaya verilmiş
messages:readkapsamı. - Go 1.26 veya üzeri.
1. SDK'yı yükleyin
go get github.com/keenauth/keenauth-go
SDK henüz yayımlanmadı. Yayımlanana kadar örnek, go.mod dosyasında bir replace yönergesiyle SDK kaynağına karşı derlenir.
2. Yapılandırın
API yapılandırmasını yalnızca ortam değişkenlerinden okur:
| Değişken | Zorunlu | Anlamı |
|---|---|---|
KEENAUTH_ISSUER |
evet | Ortamınızın veren adresi |
KEENAUTH_AUDIENCE |
evet | API'nizin tanımlayıcısı |
PUBLIC_BASE_URL |
evet | İstemcilerin çağırdığı URL (bkz. Proxy arkasında) |
KEENAUTH_WEBHOOK_SECRET |
önerilir | token.revoked gönderen webhook uç noktasının idp_whsec_ imza sırrı (döndürme sırasında virgülle ayrılmış iki değer). Bu olmadan API, iptal edilmiş belirteçleri asla öğrenmez |
ADDR |
hayır | Dinleme adresi, varsayılan :8080 |
3. Rotalarınızı koruyun
NewHandler ara katmanı ve rotaları oluşturur. m.Handler geçerli bir belirteç ister; m.Require ayrıca kapsam da ister. İşleyici, doğrulanmış talepleri protect.ClaimsFrom ile okur.
// NewHandler builds the API. The verifier is a parameter so that tests can pass the offline test kit's verifier;
// main passes a real one. The revocation cache is fed from the token.revoked webhook.
func NewHandler(v protect.AccessTokenVerifier, publicBaseURL string, revocation protect.RevocationChecker) (http.Handler, error) {
m, err := protect.New(v, protect.Options{
PublicBaseURL: publicBaseURL,
Revocation: revocation,
OnError: func(r *http.Request, err error) {
// The error never contains the token or claim values; never log the Authorization or DPoP header.
log.Printf("rejected %s %s: %v", r.Method, r.URL.Path, err)
},
})
if err != nil {
return nil, err
}
mux := http.NewServeMux()
// No token needed.
mux.HandleFunc("GET /api/public", func(w http.ResponseWriter, _ *http.Request) {
writeJSON(w, map[string]string{"message": "Hello from a public endpoint."})
})
// Any valid access token for this API.
mux.Handle("GET /api/private", m.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
claims, _ := protect.ClaimsFrom(r.Context())
writeJSON(w, map[string]string{"message": "Hello from a private endpoint.", "sub": claims.Subject})
})))
// A valid access token that also carries the messages:read scope.
mux.Handle("GET /api/messages", m.Require(protect.Requirement{Scopes: []string{"messages:read"}})(
http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
writeJSON(w, map[string]any{"messages": []string{"Hello from a scoped endpoint."}})
})))
return mux, nil
}
main yapılandırmadan gerçek doğrulayıcıyı oluşturur. Doğrulayıcı, bir belirteç gördüğü ilk seferde imza anahtarlarını ortamınızdan getirir.
func main() {
cfg, err := ConfigFromEnv(os.Getenv)
if err != nil {
log.Fatal(err)
}
// verify.New refuses an issuer under the reserved .invalid domain, so a test token can never pass here.
v, err := verify.New(verify.Config{Issuer: cfg.Issuer, Audience: cfg.Audience})
if err != nil {
log.Fatal(err)
}
revocation := protect.NewMemoryRevocationCache(0, nil)
api, err := NewHandler(v, cfg.PublicBaseURL, revocation)
if err != nil {
log.Fatal(err)
}
h := api
if len(cfg.WebhookSecrets) > 0 {
wv, err := webhook.NewVerifier(cfg.WebhookSecrets) // the error never contains the secret
if err != nil {
log.Fatalf("KEENAUTH_WEBHOOK_SECRET: %v", err)
}
h = WithWebhook(api, NewWebhookHandler(wv, revocation, nil))
} else {
log.Print("KEENAUTH_WEBHOOK_SECRET is not set: token.revoked events are not received, so revoked tokens stay valid until they expire")
}
srv := &http.Server{Addr: cfg.Addr, Handler: h, ReadHeaderTimeout: 10 * time.Second}
log.Printf("listening on %s", cfg.Addr)
log.Fatal(srv.ListenAndServe())
}
4. API'yi çalıştırın ve çağırın
export KEENAUTH_ISSUER=https://your-environment.eu.keenauth.app
export KEENAUTH_AUDIENCE=https://api.example.com
export PUBLIC_BASE_URL=https://api.example.com
go run .
İlk çağrı için, ortamınızdaki API üzerinde messages:read kapsamına sahip bir makineden makineye uygulamanın istemci kimlik bilgileri akışıyla bir belirteç alın:
ACCESS_TOKEN=$(curl -s -u "$CLIENT_ID:$CLIENT_SECRET" \
-d grant_type=client_credentials \
-d resource=https://api.example.com \
-d scope=messages:read \
https://your-environment.eu.keenauth.app/oauth2/token | jq -r .access_token)
curl -i http://localhost:8080/api/messages -H "Authorization: Bearer $ACCESS_TOKEN"
5. Ağ olmadan test edin
Test kiti paketi keenauthtest genel test anahtarıyla imzalanmış belirteçler üretir ve yalnızca bu belirteçleri kabul eden bir doğrulayıcı oluşturur. Testler bu doğrulayıcıyı NewHandler işlevine iletir; bu yüzden ağ bağlantısına ve KeenAuth hesabına ihtiyaç duymazlar. Bkz. Çevrimdışı test kiti.
func newTestAPI(t *testing.T) (http.Handler, *protect.MemoryRevocationCache) {
t.Helper()
v, err := keenauthtest.NewVerifier(verify.Config{Audience: audience})
if err != nil {
t.Fatal(err)
}
cache := protect.NewMemoryRevocationCache(0, nil)
h, err := NewHandler(v, baseURL, cache)
if err != nil {
t.Fatal(err)
}
return h, cache
}
go test ./...
Örneğin testleri, geçerli bir belirtecin kabul edildiğini; eksik, süresi dolmuş veya yanlış hedef kitleli belirtecin, eksik kapsamın, URL sorgusundaki bir belirtecin ve iptal edilmiş bir belirtecin aşağıdaki durum kodlarıyla reddedildiğini denetler. Ayrıca PUBLIC_BASE_URL için bir kanıtla birlikte DPoP'a bağlı bir belirteç gönderirler. Testler ayrıca imzalı token.revoked teslimatları gönderir: geçerli bir teslimat belirteci iptal eder; sahte, değiştirilmiş veya eski bir teslimat 400 yanıtı alır ve hiçbir şeyi iptal etmez; tekrarlanan bir teslimatın etkisi tek olur.
Yanıtlar
| İstek | Durum | Gövdede code |
|---|---|---|
Authorization başlığı olmayan |
401 |
missing_token |
| Süresi dolmuş belirteç, başka bir API için belirteç, hatalı imza, iptal edilmiş belirteç | 401 |
invalid_token |
| Gerekli kapsamı olmayan belirteç | 403 |
insufficient_scope |
URL sorgusundaki belirteç (?access_token=) |
400 |
invalid_request |
Gövde application/problem+json ve WWW-Authenticate başlığı standart meydan okumayı taşır. Tam tablo ara katmanla API'nizi koruma sayfasındadır.
Proxy arkasında
İstemciler DPoP kullanıyorsa, ara katman her kanıtın istemcinin çağırdığı URL için yapıldığını denetler. PUBLIC_BASE_URL değerini, istemcilerin çağırdığı dış URL'ye ayarlayın, örneğin https://api.example.com; proxy veya yük dengeleyici arkasında da böyledir. Zorunludur ve https kullanmalıdır (http yalnızca localhost, 127.0.0.1 veya [::1] için); bu olmadan uygulama başlamayı reddeder. Ara katman X-Forwarded-* başlıklarına asla güvenmez.
İptal edilmiş belirteçler
Erişim belirteci süresi dolana kadar geçerli kalır; bu yüzden KeenAuth, belirteçler iptal edildiğinde API'nize bildirir. Örnek, ara katmana bellek içi bir iptal önbelleği verir ve bunu besleyen bir token.revoked webhook'unu POST /webhooks/keenauth adresinde (main.go, webhook.go) sunar.
- Panelde,
https://<your host>/webhooks/keenauthURL'sine sahip vetoken.revokedolaylarına abone olan bir webhook uç noktası oluşturun ve imza sırrınıKEENAUTH_WEBHOOK_SECRETolarak dışa aktarın. - İşleyici, imzayı ham gövde üzerinde SDK ile doğrular ve geçersizse ya da zaman damgası beş dakikadan fazla sapmışsa
400yanıtı verir. Olayın seçicisini (access_token,session,user,client,org,org_user,client_user) bir iptal işaretçisine eşler ve204yanıtı verir; ara katman bundan sonranot_beforeöncesinde verilmiş eşleşen tüm belirteçleri reddeder. - KeenAuth en az bir kez teslim eder, bu yüzden işleyici her
webhook-iddeğerini bir kez uygular. İşaretçi kaydedilemezse503yanıtı verir ve KeenAuth olayı yeniden teslim eder. Diğer olay türlerini ve hiçbir erişim belirtecinin eşleşemeyeceği seçicileri (refresh_family,api) yok sayar.
İşleyici olay kimliğini, seçici türünü ve nedeni kaydeder; gövdeyi, imzayı veya sırrı asla kaydetmez. Her süreç kendi önbelleğine sahiptir; birden fazla örnekle çalışırken işaretçileri, aynı Revoke yöntemi arkasında paylaşılan bir depoya koyun. Bkz. İptal önbelleği.
Sonraki adımlar
- Ara katmanla API'nizi koruma: adım yukarı gereksinimleri, DPoP ve her seçenek.
- Belirteçleri doğrulama: ara katmanın altındaki doğrulayıcı.
- Çevrimdışı test kiti.