SDK Go: paket xguard
Paket Go untuk menyambungkan aplikasi ke SSO X-Guard organisasi. Hanya bergantung pada coreos/go-oidc/v3 dan golang.org/x/oauth2. Minimal Go 1.24.
| Fungsi | Untuk |
|---|---|
New(ctx, Config) | Baca discovery issuer organisasi, siapkan client |
StartLogin(w, r, returnTo, opts...) | Arahkan browser ke login X-Guard (PKCE S256, state, nonce). xguard.Silent() = prompt=none |
HandleCallback(w, r) | Tukar code, verifikasi ID token → *Identity (termasuk Org dari access token) |
LogoutURL(idToken) | URL logout (RP-initiated); semua aplikasi organisasi ikut keluar |
BackchannelLogoutHandler(fn) | Endpoint back-channel logout (X-Guard → aplikasi) |
WebhookHandler(secret, fn) | Endpoint webhook user.* dan webhook.ping (header X-XGuard-*) |
RequireAccessToken(next) | Middleware API untuk access token JWT dari X-Guard (Org, Scopes, Audience) |
Memakai
Unduh x-guard-sdk-go.zip (atau ambil per berkas di daftar berkas), salin folder xguard ke internal/xguard di aplikasi, lalu go get github.com/coreos/go-oidc/[email protected] golang.org/x/[email protected] github.com/go-jose/go-jose/[email protected].
go
sso, err := xguard.New(ctx, xguard.Config{
Issuer: os.Getenv("XGUARD_ISSUER"), // https://nama-organisasi.x-guard.online
ClientID: os.Getenv("XGUARD_CLIENT_ID"),
ClientSecret: os.Getenv("XGUARD_CLIENT_SECRET"),
RedirectURL: "https://app.contoh.id/auth/callback",
PostLogoutRedirectURL: "https://app.contoh.id/",
})
mux.HandleFunc("GET /auth/login", func(w http.ResponseWriter, r *http.Request) {
sso.StartLogin(w, r, r.URL.Query().Get("next"))
})
mux.HandleFunc("GET /auth/callback", func(w http.ResponseWriter, r *http.Request) {
id, next, err := sso.HandleCallback(w, r)
if errors.Is(err, xguard.ErrLoginRequired) { sso.StartLogin(w, r, next); return } // sesi X-Guard berakhir → login biasa
if errors.Is(err, xguard.ErrAccessDenied) { /* pengguna tidak diberi akses ke aplikasi ini */ }
if err != nil { /* *xguard.AuthError lain = state salah / kedaluwarsa */ }
// 1. cari user lokal by xguard_sub = id.Subject, fallback email bila id.EmailVerified (lalu isi xguard_sub)
// 2. buat sesi aplikasi; simpan id.SessionID (back-channel) dan id.IDToken (logout)
http.Redirect(w, r, next, http.StatusFound)
})
mux.Handle("POST /auth/backchannel-logout", sso.BackchannelLogoutHandler(
func(ctx context.Context, lt *xguard.LogoutToken) error { return sessions.RevokeBySID(ctx, lt.SessionID) }))
mux.Handle("POST /auth/webhook", xguard.WebhookHandler(os.Getenv("XGUARD_WEBHOOK_SECRET"),
func(ctx context.Context, ev *xguard.Event) error {
// Idempoten berdasarkan ev.ID. Sub tidak dikenal → return nil.
// user.disabled, user.deleted, atau user.apps_changed dengan ev.Access == xguard.AccessRevoked → cabut sesinya.
return nil // error → X-Guard mencoba ulang
}))
// logout: hapus sesi aplikasi lalu http.Redirect(w, r, sso.LogoutURL(sess.IDToken), http.StatusSeeOther)Dengan Gin: sso.StartLogin(c.Writer, c.Request, next), sso.HandleCallback(c.Writer, c.Request), r.POST(path, gin.WrapH(sso.BackchannelLogoutHandler(fn))).
Tes
bash
go test ./... # memakai X-Guard palsu, tidak butuh serverDiangkat dari pkg/ssoauth SSO internal; aplikasi lama cukup mengganti import dan issuer.