Route guard yazmak: Angular rotalarını giriş ve rol kurallarıyla korumak
Beceri rehberi

Route guard yazmak: Angular rotalarını giriş ve rol kurallarıyla korumak

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 5 dk okuma

Angular route guard ile giriş kontrolü, rol bazlı erişim ve kaydedilmemiş değişiklik uyarısı: canActivate, canMatch ve yönlendirme örnekleri.

Route guard ne işe yarar?

Route guard, bir rotaya girilmeden önce ya da rotadan çıkılırken çalışan ve izin verip vermeyeceğine karar veren bir fonksiyondur. Tipik kullanım: giriş yapmamış kullanıcıyı giriş sayfasına yollamak, yönetici sayfasına yalnızca yönetici rolündekileri almak, kaydedilmemiş form değişikliği varken sayfadan ayrılmayı engellemek.

Önemli bir uyarı resmî belgede açıkça yer alır: istemci tarafı guard'ları erişim denetiminin tek kaynağı olmamalıdır. Tarayıcıdaki kod kullanıcı tarafından değiştirilebilir. Guard, kullanıcıya doğru ekranı göstermek içindir; asıl yetki denetimi sunucuda, API tarafında yapılmalıdır. Bu ayrımı baştan kabul etmek, yetkilendirme tasarımının temelidir.

Guard türleri ve ne zaman hangisi

Belgede temel guard türleri şöyle sayılır. canActivate, bir rotaya girilebilir mi sorusunu yanıtlar ve giriş ve yetki kontrolü için en yaygın olanıdır. canActivateChild, bir üst rotanın tüm alt rotaları için çalışır ve iç içe yapılarda tek noktada koruma sağlar. canDeactivate, kullanıcının rotadan çıkıp çıkamayacağını belirler; kaydedilmemiş form uyarısı için kullanılır. canMatch ise rota tanımının eşleşmeye katılıp katılmayacağına karar verir; false dönerse yönlendirici diğer eşleşen rotaları dener.

Seçim ölçütü: giriş ve rol için canActivate; yönetim alanının tüm alt sayfalarını tek kuralla korumak için canActivateChild; form kaybını önlemek için canDeactivate; özellik bayrağı ya da role göre farklı rota yüklemek (örneğin yönetici için farklı bir panel) için canMatch. canMatch ayrıca, korumalı bölümün kodunu kullanıcıya hiç yüklememek için tembel yüklenen rotalarda da işe yarar.

Giriş kontrolü guard'ı: adım adım

Fonksiyonel guard yazmak için bir CanActivateFn tanımlanır; içeride gerekli servisler inject ile alınır. Belgedeki kalıba uygun örnek:

export const girisGuard: CanActivateFn = (route, state) => { const oturum = inject(OturumServisi); const router = inject(Router); return oturum.girisYapildiMi() || router.parseUrl('/giris'); };

Guard doğruysa true döner ve rota açılır; değilse giriş sayfasına bir UrlTree döner. Belge, engellemek için false dönüp ayrıca navigate çağırmak yerine UrlTree ya da RedirectCommand ile yönlendirmeyi tercih etmeyi önerir. Böylece yönlendirme tek bir dönüş değerinde ifade edilir ve çakışan gezinmeler önlenir.

Rota tanımına eklemek: { path: 'panel', component: Panel, canActivate: [girisGuard] }. Giriş sonrası kullanıcıyı gitmek istediği sayfaya döndürmek için, yönlendirme adresine gidilen URL'yi bir sorgu parametresi olarak ekleyebilirsiniz; giriş başarılı olunca bu adrese gidilir.

Rol bazlı erişim: parametreli guard

Her rol için ayrı bir guard yazmak yerine, rotanın data alanına gerekli rolü koyup tek bir guard'da okumak daha sürdürülebilirdir:

{ path: 'admin', component: AdminPage, data: { rol: 'admin' }, canActivate: [rolGuard] }

export const rolGuard: CanActivateFn = (route) => { const oturum = inject(OturumServisi); const gerekli = route.data['rol']; return oturum.rolVarMi(gerekli) || inject(Router).parseUrl('/yetkisiz'); };

Böylece yeni bir korumalı rota eklemek, yalnızca rota tanımına bir data satırı eklemek demektir. Yetkisiz kullanıcıyı giriş sayfasına değil, nedenini açıklayan ayrı bir "yetkiniz yok" sayfasına yönlendirmek kullanıcı deneyimini iyileştirir; giriş yapmış ama yetkisi olmayan kişiyle henüz giriş yapmamış kişi farklı muamele görmelidir.

Rol bilgisi oturum servisinde tutulur ve sunucudan alınan kimlik bilgisinden gelir. Rol ya da yetki değişirse ön yüzdeki önbelleğin güncel olduğundan emin olun; eski yetkiyle açık kalan oturum, sunucu tarafında yine de reddedilmelidir.

Kaydedilmemiş değişiklik: canDeactivate

Uzun bir form doldururken yanlışlıkla başka bir sayfaya geçmek veri kaybettirir. canDeactivate bunu önler. Belgedeki yapı: guard, bileşen örneğini alır ve bileşenin bir metoduna sorar.

export const kayitGuard: CanDeactivateFn<FormSayfasi> = (sayfa) => { return sayfa.degisiklikVarMi() ? confirm('Kaydedilmemiş değişiklikler var. Ayrılmak istiyor musunuz?') : true; };

Rotaya canDeactivate: [kayitGuard] olarak eklenir. Pratikte tarayıcının kendi confirm penceresi yerine özel bir onay iletişim kutusu da açabilirsiniz; guard bir Observable ya da Promise döndürebilir ve yönlendirici ilk yayılan değeri kullanır. Reaktif formlarda dirty durumu, değişiklik var mı sorusunu yanıtlamak için hazır bir göstergedir.

Guard sırası ve eşzamanlılık

Bir rotaya birden çok guard bağlandığında bilinmesi gereken önemli bir ayrıntı vardır: belgeye göre dizideki guard'lar eşzamanlı çalışır. Bu yüzden bir guard'ın, aynı dizideki başka bir guard'ın yaptığı işe güvenmesi doğru değildir; örneğin "önce oturum yüklensin, sonra rol kontrol edilsin" bağımlılığı varsa bunu tek bir guard içinde ya da üst rotada ifade edin. Yönlendirici, true dönmeyen ilk guard'ın sonucunu kullanır.

Pratik düzen: iç içe yapılarda giriş kontrolünü üst rotaya, rol kontrolünü alt rotaya koyun; üst guard'ın başarısız olduğu durumda alt rotalar zaten açılmaz. Guard içinde ağır iş yapmayın; oturum bilgisi servis tarafından önceden yüklenmiş olmalı, guard yalnızca karar vermelidir. Uzun süren bir guard, kullanıcıya ekranın donduğu hissini verir.

Sık hatalar ve Mindset bağlamı

Sık yapılan hatalar: yetkiyi yalnızca ön yüzde denetleyip API'yi korumasız bırakmak, guard içinde false dönüp navigate çağırarak yarış durumları yaratmak, rol bilgisini her seferinde sunucudan beklemek, yetkisiz ve girişsiz kullanıcıyı aynı sayfaya göndermek ve canMatch ile tembel yükleme avantajını göz ardı etmek.

Mindset'in Angular ile Kurumsal Web Uygulamaları programındaki "Formlar, Yönlendirme ve Yetkilendirme" modülü, bu konuyu form ve rota yapısıyla birlikte ele alır. Çok rollü kurumsal yönetim ekranları geliştiren ekipler için uygundur; çünkü rol bazlı erişim kuralları çoğunlukla hem arayüzde hem sunucuda tutarlı kurgulanmak zorundadır.

İlgili Mindset programı

Angular ile Kurumsal Web Uygulamaları

Sık sorulanlar

Sık sorulan sorular

Guard yetkilendirme için yeterli mi?

Hayır. Resmî belgenin de vurguladığı gibi istemci tarafı guard yalnızca arayüz akışını yönlendirir. Tarayıcıdaki kod değiştirilebileceği için asıl yetki denetimi sunucuda, her API isteğinde yapılmalıdır. Guard, kullanıcıya yetkisiz olduğu sayfayı hiç göstermemek için tamamlayıcı bir katmandır.

canActivate ile canMatch arasındaki fark nedir?

canActivate, rota eşleştikten sonra girişe izin verilip verilmeyeceğini belirler. canMatch ise rota tanımının eşleşmeye katılıp katılmayacağına karar verir; false dönerse yönlendirici sıradaki eşleşen rotayı dener. Özellik bayrağı ya da role göre farklı sayfa göstermek gerekiyorsa canMatch daha uygundur.

Guard'dan nasıl yönlendirme yapılır?

Belge, false dönüp ayrıca navigate çağırmak yerine UrlTree ya da RedirectCommand döndürmeyi önerir. Router.parseUrl ile adresi UrlTree olarak üretip dönmeniz yeterlidir. Böylece yönlendirme tek bir dönüş değerinde ifade edilir ve gezinme çakışmaları önlenir.

Guard asenkron çalışabilir mi?

Evet. Guard boolean, UrlTree ya da bunları döndüren bir Promise veya Observable verebilir; yönlendirici ilk yayılan değeri kullanır. Oturum kontrolünü sunucuya sormanız gerekiyorsa Observable döndürebilirsiniz. Yine de uzun süren işlemler kullanıcıya bekleme hissi verdiği için mümkünse oturum bilgisini önceden yükleyin.

Guard nasıl test edilir?

Fonksiyonel guard bir fonksiyon olduğu için, enjeksiyon bağlamı içinde çağrılarak test edilir. Bağımlı servisler TestBed ile sahte sürümlerle değiştirilir; test, giriş yapılmış ve yapılmamış durumları ayrı ayrı çalıştırıp dönen değerin true ya da UrlTree olduğunu doğrular.

Angular Route Guard ile Sayfa Yetkilendirme