Documentation
¶
Overview ¶
Package gti, GlobalTrustID'nin resmî Go istemcisidir.
Üç işi yapar:
- "GlobalTrustID ile giriş" — OAuth 2.0 / OpenID Connect, PKCE (S256) ile.
- Kimlik doğrulama — QR oluşturur, kullanıcı telefonuyla onaylar.
- Webhook doğrulama — gelen bildirimin gerçekten bizden geldiğini kanıtlar.
DIŞ BAĞIMLILIK YOK: yalnızca standart kütüphane. Kimlik doğrulama altyapısına bağlanan bir paketin kendi bağımlılık ağacını getirmemesi, denetlenebilirliği doğrudan etkiliyor.
İki ayrı kimlik bilgisi ¶
APIKey ile ClientSecret AYNI ŞEY DEĞİLDİR ve karıştırılmaları çalışmayan entegrasyonların en sık sebebi:
- ClientID + ClientSecret: OAuth uygulamanız. Panel → Entegrasyonlar → OAuth Uygulamaları. Giriş akışında kullanılır.
- APIKey (sk_live_...): organizasyonunuzun API anahtarı. Panel → API Keys. Kimlik doğrulama oturumlarında kullanılır.
Yalnızca giriş yapacaksanız APIKey'e, yalnızca kimlik doğrulaması yapacaksanız ClientID/ClientSecret'a ihtiyacınız yok.
Örnek ¶
client, err := gti.New(gti.Config{
ClientID: "gtid_...",
RedirectURI: "https://siteniz.com/gti/callback",
})
// Yönlendirme
login, _ := client.BeginLogin(gti.ScopeOpenID)
// login.State ve login.Verifier'ı OTURUMUNUZDA saklayın
http.Redirect(w, r, login.URL, http.StatusFound)
// Callback
tokens, err := client.CompleteLogin(ctx, r.URL.Query(), state, verifier)
Index ¶
- Constants
- Variables
- func ChipOnlyScopes() []string
- type APIError
- type Client
- func (c *Client) BeginLogin(scope ...string) (*LoginRequest, error)
- func (c *Client) CompleteLogin(ctx context.Context, query url.Values, expectedState, verifier string) (*TokenSet, error)
- func (c *Client) CreateSession(ctx context.Context, scope []string, webhookURL string) (*Session, error)
- func (c *Client) Exchange(ctx context.Context, code, verifier string) (*TokenSet, error)
- func (c *Client) FetchSession(ctx context.Context, sessionID string) (*SessionResult, error)
- func (c *Client) FetchUserInfo(ctx context.Context, accessToken string) (*UserInfo, error)
- func (c *Client) QRURL(sessionID string) string
- func (c *Client) Refresh(ctx context.Context, refreshToken string) (*TokenSet, error)
- func (c *Client) VerifyWebhook(body []byte, signature, timestamp string, tolerance time.Duration) error
- func (c *Client) VerifyWebhookRequest(r *http.Request, body []byte, tolerance time.Duration) error
- type Config
- type LoginRequest
- type OAuthError
- type Session
- type SessionResult
- type TokenSet
- type UserInfo
Constants ¶
const ( DefaultAPIBase = "https://api.globaltrust.id" DefaultIssuer = "https://globaltrust.id" )
Varsayılan adresler. Kurulumunuz farklıysa Config'ten geçin.
const ( SignatureHeader = "X-GTI-Signature" TimestampHeader = "X-GTI-Timestamp" EventHeader = "X-GTI-Event" )
Webhook başlıkları.
const DefaultWebhookTolerance = 5 * time.Minute
DefaultWebhookTolerance, kabul edilen azami zaman sapması.
const ScopeOpenID = "openid"
ScopeOpenID, yalnızca kimlik doğrulama: hiçbir kişisel veri paylaşılmaz.
Kullanıcının onay ekranında "hiçbir bilgin paylaşılmıyor" yazar. Ad, e-posta gibi alanlara gerçekten ihtiyacınız varsa açıkça isteyin — istemediğiniz veri size gelmez.
const Version = "0.1.0"
Version, User-Agent'ta gider; destek talebinde işe yarar. Git etiketiyle aynı tutulmalı.
Variables ¶
var ( // ErrConfig, istemci eksik ya da tutarsız yapılandırıldı. İstek hiç // gönderilmedi. ErrConfig = errors.New("gti: yapılandırma eksik") // ErrStateMismatch, dönüş adresindeki state beklenenle uyuşmadı. // Giriş DURDURULMALI: bu, akışı başlatanın kullanıcı olmadığı anlamına // gelebilir (CSRF). ErrStateMismatch = errors.New("gti: state eşleşmedi") // ErrDenied, kullanıcı onay vermedi ya da sunucu isteği reddetti. ErrDenied = errors.New("gti: giriş reddedildi") // ErrTransport, sunucuya ulaşılamadı. API hatasından AYRI: birincisi // bizim ulaşamamamız, ikincisi sunucunun "hayır" demesi ve ikisi farklı // davranmayı gerektirir (yeniden dene / deneme). ErrTransport = errors.New("gti: sunucuya ulaşılamadı") )
Sentinel hatalar. errors.Is ile karşılaştırılmak üzere.
Hata METNİNE göre dallanmak zorunda kalınmasın diye ayrı değerler: metin değişebilir ve çevrilebilir, sentinel sözleşmenin parçası.
Functions ¶
func ChipOnlyScopes ¶
func ChipOnlyScopes() []string
ChipOnlyScopes, çipten okunmadan doldurulamayan scope listesinin kopyasını verir.
Types ¶
type APIError ¶
type APIError struct {
Code int
Message string
// HTTPStatus, yanıtın HTTP durum kodu.
HTTPStatus int
}
APIError, sunucunun zarflı yanıtındaki hata (/api/v1/... uçları).
Zarf biçimi: {status, data, error_code, error_message}
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client, GlobalTrustID istemcisi. Eşzamanlı kullanıma uygundur.
func New ¶
New, istemciyi kurar.
Yapılandırma burada DOĞRULANMIYOR: hangi alanların gerekli olduğu yapılacak işe göre değişiyor ve yalnızca webhook doğrulaması yapan biri ClientID vermek zorunda değil. Eksiklik, o alana ihtiyaç duyan çağrıda ErrConfig olarak bildiriliyor — istek gönderilmeden.
func (*Client) BeginLogin ¶
func (c *Client) BeginLogin(scope ...string) (*LoginRequest, error)
BeginLogin, giriş adresini ve saklanması gereken değerleri üretir.
login, err := client.BeginLogin(gti.ScopeOpenID)
session.Put("gti_state", login.State)
session.Put("gti_verifier", login.Verifier)
http.Redirect(w, r, login.URL, http.StatusFound)
func (*Client) CompleteLogin ¶
func (c *Client) CompleteLogin(ctx context.Context, query url.Values, expectedState, verifier string) (*TokenSet, error)
CompleteLogin, callback'teki sorgu dizesini token'a çevirir.
expectedState ve verifier, BeginLogin'den alıp sakladığınız değerler.
tokens, err := client.CompleteLogin(ctx, r.URL.Query(), state, verifier)
if errors.Is(err, gti.ErrDenied) { /* kullanıcı vazgeçti */ }
func (*Client) CreateSession ¶
func (c *Client) CreateSession(ctx context.Context, scope []string, webhookURL string) (*Session, error)
CreateSession, kimlik doğrulama oturumu açar.
webhookURL boş bırakılabilir; verilirse sonuç hazır olduğunda oraya POST edilir ve kullanıcı tarayıcıyı kapatsa bile size ulaşır.
func (*Client) FetchSession ¶
FetchSession, bir oturumun güncel durumunu ve varsa sonucunu okur.
func (*Client) FetchUserInfo ¶
FetchUserInfo, erişim token'ıyla onaylanan alanları okur.
func (*Client) QRURL ¶
QRURL, oturumun hazır QR görselinin adresi (SVG).
Kendi QR kütüphanenizi kullanmak isterseniz Session.QR alanındaki metni kodlayın; bu adres sunucunun ürettiği hazır görsel.
func (*Client) VerifyWebhook ¶
func (c *Client) VerifyWebhook(body []byte, signature, timestamp string, tolerance time.Duration) error
VerifyWebhook, gelen webhook'un gerçekten bizden geldiğini doğrular.
BU ADIMI ATLAMAYIN. Webhook adresiniz herkese açıktır; imzayı doğrulamadan gövdeye güvenirseniz, size sahte bir "approved" gönderen herkes kimlik doğrulamasını atlatmış olur.
body HAM BAYTLAR olmalı. JSON'u çözüp yeniden kodlarsanız boşluk ve anahtar sırası değişir, imza tutmaz.
tolerance sıfır ya da negatifse zaman kontrolü yapılmaz. Bunu yalnızca kuyruğa alınmış webhook'ları sonradan işliyorsanız kullanın: zaman kontrolü, geçerli bir isteği kaydedip sonra tekrar gönderen birine (replay) karşı koruyor.
func (*Client) VerifyWebhookRequest ¶
VerifyWebhookRequest, başlıkları istekten okuyup VerifyWebhook'u çağırır.
body'yi SİZ okuyup vermelisiniz: http.Request.Body tek kullanımlık, ve burada okusaydık siz aynı gövdeyi bir daha okuyamazdınız.
body, _ := io.ReadAll(r.Body)
if err := client.VerifyWebhookRequest(r, body, gti.DefaultWebhookTolerance); err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
type Config ¶
type Config struct {
// OAuth uygulaması — "GlobalTrustID ile giriş" için.
ClientID string
RedirectURI string
// ClientSecret YALNIZCA confidential istemcide doldurulur. Public
// istemcide (SPA, mobil) sır yoktur ve akışı PKCE korur — boş bırakın.
// Boş bir dize göndermek sunucuya "sırrım var ama boş" demektir.
ClientSecret string
// APIKey (sk_live_... / sk_test_...) — kimlik doğrulama oturumları için.
APIKey string
// WebhookSecret, gelen webhook'un imzasını doğrulamak için.
WebhookSecret string
// APIBase ve Issuer boşsa varsayılanlar kullanılır.
APIBase string
Issuer string
// HTTPClient verilmezse 15 saniye zaman aşımlı bir istemci kurulur.
//
// Kendi istemcinizi vermek isteyebilirsiniz: bağlantı havuzu, proxy ya da
// izleme (tracing) eklemek için. Yalnızca dikkat: yönlendirmeleri İZLEYEN
// bir istemci, Authorization başlığı taşıyan bir isteği başka bir hosta
// göndererek gizli anahtarı oraya sızdırabilir.
HTTPClient *http.Client
}
Config, istemcinin yapılandırması.
type LoginRequest ¶
type LoginRequest struct {
// URL, kullanıcıyı yönlendireceğiniz adres.
URL string
// State, CSRF koruması. Callback'te dönen değerle karşılaştırılıyor.
State string
// Verifier, PKCE doğrulayıcısı. GİZLİ: yalnızca token değişiminde
// sunucuya gidiyor, yönlendirme adresinde asla görünmüyor.
Verifier string
}
LoginRequest, BeginLogin'in ürettiği tek seferlik giriş isteği.
STATE VE VERIFIER SAKLANMAK ZORUNDA. İkisi de callback'te gerekiyor ve bu paket onları sizin adınıza saklamıyor — oturum yönetimi sizin çerçevenizin işi (çerez, Redis, veritabanı). Bir oturum soyutlaması uydurmak, her kurulumda yanlış olurdu.
type OAuthError ¶
type OAuthError struct {
Code string // "invalid_grant", "invalid_client", ...
Description string
HTTPStatus int
}
OAuthError, OAuth/OIDC uçlarının hatası. Bu uçlar zarf kullanmıyor; hata RFC 6749 §5.2 biçiminde geliyor.
func (*OAuthError) Error ¶
func (e *OAuthError) Error() string
func (*OAuthError) Is ¶
func (e *OAuthError) Is(target error) bool
Is, kullanıcının vazgeçtiği hâlin ErrDenied ile yakalanmasını sağlar: access_denied bir arıza değil, meşru bir sonuç.
type Session ¶
type Session struct {
SessionID string `json:"session_id"`
// QR, karekodun içine yazılacak METİN. Kodu kendiniz üretmek isterseniz
// bunu kullanın; hazır görsel için QRURL.
QR string `json:"qr"`
Scope []string `json:"scope"`
Status string `json:"status"`
ExpiresAt string `json:"expires_at"`
}
Session, açılan doğrulama oturumu.
type SessionResult ¶
type SessionResult struct {
SessionID string `json:"session_id"`
// Status: waiting | scanned | opened | approved | declined | expired
Status string `json:"status"`
Scope []string `json:"scope"`
// Identity yalnızca approved durumunda ve sonuç henüz silinmediyse dolu.
// Sonuçlar kısa süre sonra kendiliğinden yok oluyor — kalıcı saklanmazlar.
Identity map[string]string `json:"identity,omitempty"`
ExpiresAt string `json:"expires_at"`
}
SessionResult, oturumun okunan sonucu.
func (SessionResult) Approved ¶
func (r SessionResult) Approved() bool
Approved, oturum onaylandı mı.
func (SessionResult) IdentityVerified ¶
func (r SessionResult) IdentityVerified() bool
IdentityVerified, kullanıcının kimlik BELGESİNİ gerçekten okutup okutmadığını söyler.
Ad ve e-posta gibi alanlar kullanıcının kendi yazdığı profilden de gelebilir; belge numarası ve kimlik numarası gelemez — onlar yalnızca NFC ile okunan çipten çıkar. Bu yüzden "bu kişi kimliğini doğruladı mı?" sorusunun cevabı, sonuçta bu alanlardan birinin bulunup bulunmadığıdır.
type TokenSet ¶
type TokenSet struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token,omitempty"`
// IDToken bir JWT. Doğrulamadan içeriğine güvenmeyin.
IDToken string `json:"id_token,omitempty"`
// Scope, kullanıcının FİİLEN onayladığı alanlar — istediğinizden dar
// olabilir. Yetkiyi buna göre kurun, istediğinize göre değil.
Scope string `json:"scope"`
}
TokenSet, token ucunun yanıtı.
type UserInfo ¶
type UserInfo struct {
Subject string `json:"sub"`
GivenName string `json:"given_name,omitempty"`
FamilyName string `json:"family_name,omitempty"`
Name string `json:"name,omitempty"`
Birthdate string `json:"birthdate,omitempty"`
Gender string `json:"gender,omitempty"`
Email string `json:"email,omitempty"`
PhoneNumber string `json:"phone_number,omitempty"`
Address string `json:"address,omitempty"`
Nationality string `json:"nationality,omitempty"`
NationalID string `json:"national_id,omitempty"`
DocumentNumber string `json:"document_number,omitempty"`
PassportNumber string `json:"passport_number,omitempty"`
Picture string `json:"picture,omitempty"`
// AgeOver18, doğum tarihi paylaşılmadan "true"/"false".
AgeOver18 string `json:"age_over_18,omitempty"`
}
UserInfo, /oauth/userinfo yanıtı. Alanlar yalnızca onaylanan scope kadar dolu; istemediğiniz bir alan hiç gelmez.
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
login
command
ÖRNEK 1 — "GlobalTrustID ile giriş" (OAuth 2.0 / OIDC).
|
ÖRNEK 1 — "GlobalTrustID ile giriş" (OAuth 2.0 / OIDC). |
|
verify
command
ÖRNEK 2 — QR ile kimlik doğrulama.
|
ÖRNEK 2 — QR ile kimlik doğrulama. |
|
webhook
command
ÖRNEK 3 — Webhook alıcısı.
|
ÖRNEK 3 — Webhook alıcısı. |