Açısal Durdurucularda Sorunsuz JWT Yenilemesinin Sağlanması
Güvenli kullanıcı oturumlarına sahip bir web uygulamasında kısa ömürlü JWT belirteçlerini etkili bir şekilde yönetmek, kesintisiz kullanıcı deneyimi için çok önemlidir. Belirteçlerin süresi dolduğunda, kullanıcılar sıklıkla yeniden oturum açmaya zorlanma gibi sorunlarla karşılaşır ve bu durum sinir bozucu olabilir ve kullanıcı etkileşimini kesintiye uğratabilir. Bu sorunun üstesinden gelmek için geliştiriciler genellikle süresi dolmuş oturumları yönetmek için bir Angular önleyici kullanarak otomatik belirteç yenileme uygular. 🕰️
Bu yaklaşım, HTTP isteklerinin ele geçirilmesini, 401 hatalarının (yetkisiz istekler) yakalanmasını ve ardından yeni bir belirteç elde etmek için bir yenileme işleminin başlatılmasını içerir. Ancak güncellenen belirtecin veya tanımlama bilgisinin yeniden denenen isteklere uygulanmasını sağlama konusunda sorunlar ortaya çıkabilir. Yeni belirteç doğru şekilde yayılmazsa yeniden deneme başarısız olabilir, kullanıcılar aynı yetkilendirme hatasıyla karşı karşıya kalabilir ve potansiyel olarak uygulama iş akışları kesintiye uğrayabilir.
Bu kılavuzda, bu durdurucu modelinin pratik bir uygulamasını anlatacağız. Hataları nasıl yakalayacağımıza, belirteçleri nasıl yenileyeceğimize ve isteklerin geçerli yetkilendirmeyle yeniden denenmesini nasıl onaylayacağımıza bakacağız. Bu yaklaşım, oturum yenileme süreci üzerinde kontrol sahibi olmanızı sağlarken kesintileri en aza indirir.
Sonunda, HttpOnly çerezlerini işlemek ve yüksek istek hacimleri sırasında yenileme sıralarını yönetmek gibi yaygın karşılaşılan tehlikeleri nasıl çözeceğiniz konusunda fikir sahibi olacaksınız. Bu yöntem, uygulamanızın sürekli oturum açmaya gerek kalmadan güvenli ve sorunsuz bir kullanıcı oturumu sürdürmesini sağlar. 🔒
Emretmek | Kullanım örneği |
---|---|
catchError | HTTP istekleri sırasında ortaya çıkan hataları yakalamak ve işlemek için Gözlenebilir bir ardışık düzen içinde kullanılır, böylece önleyicinin özellikle belirteçleri yenilemek veya yetkisiz istekleri işlemek için 401 hatalarını engellemesine olanak tanır. |
switchMap | Yeni bir gözlemlenebilire geçiş yapar ve burada genellikle bir belirteç yenilendikten sonra HTTP yeniden denemesini işlemek için kullanılır. Akışları değiştirerek, önceki gözlemlenebilirin yerini alır ve yalnızca yeni belirteçle yeniden denenen isteğin işlenmesini sağlar. |
BehaviorSubject | HTTP istekleri genelinde belirteç yenileme durumunu korumak için kullanılan özel bir RxJS konusu. Normal Subject'in aksine BehaviorSubject, eşzamanlı 401 hatalarının işlenmesinde yardımcı olan son yayılan değeri korur. |
clone | HttpRequest nesnesini withCredentials: true gibi güncellenmiş özelliklerle kopyalar. Bu, orijinal istek yapılandırması korunarak çerezlerin istekle birlikte gönderilmesine olanak tanır. |
pipe | Birden çok RxJS operatörünü bir Gözlemlenebilir'de birlikte zincirler. Bu önleyicide, token yenilemesinden sonra hata işleme ve yeniden deneme mantığını oluşturmak için boru önemlidir. |
of | Bir değerden gözlemlenebilirlik oluşturan bir RxJS yardımcı programı. Testlerde,freshToken'dan gelen başarılı yanıtı simüle etmek için of(true) kullanılır ve önleyicinin birim testlerine yardımcı olur. |
HttpTestingController | Angular'ın test modülünden, bir test ortamında HTTP isteklerinin ele geçirilmesine ve kontrol edilmesine olanak tanıyan bir yardımcı program. Yanıtların simüle edilmesine ve isteklerin önleyici tarafından doğru şekilde yerine getirildiğinin iddia edilmesine yardımcı olur. |
flush | Bir test içindeki bir HTTP isteğini manuel olarak tamamlamak için HttpTestingController ile birlikte kullanılır ve 401 Yetkisiz gibi yanıtların simülasyonuna olanak tanır. Bu, önleyicinin yenileme mantığının beklendiği gibi etkinleşmesini sağlar. |
getValue | Bu önleyicide belirteç yenileme işleminin zaten devam edip etmediğini doğrulamak ve birden fazla yenileme isteğini önlemek için gerekli olan bir BehaviorSubject'in geçerli değerine erişir. |
Açısal Durdurucularla Güvenilir JWT Kimlik Doğrulamasının Sağlanması
Yukarıdaki örnekte, önleyici, 401 hatasıyla karşılaşıldığında kısa ömürlü bir JWT tokenını otomatik olarak yenileyecek şekilde tasarlanmıştır. Bu tür bir kurulum, oturum güvenliğinin korunmasının kritik olduğu ancak kullanıcı deneyiminin kesintiye uğramaması gereken, hassas verilere sahip uygulamalarda gereklidir. Durdurucu 401 (Yetkisiz) hatasını yakalar ve kullanıcının yeniden kimlik doğrulaması yapmasına gerek kalmadan oturumu yenilemek için bir yenileme jetonu isteği başlatır. Bu süreç, gözlemlenebilir bir işlem hattında hata yönetimine izin veren catchError işlevi tarafından tetiklenir. Burada herhangi bir HTTP hatası, özellikle de 401, tokenın süresinin dolduğuna işaret eder ve yenileme işlemini başlatır.
switchMap işlevi buradaki diğer bir temel öğedir; tüm akışı iptal etmeden eski gözlemlenebilirin yerini alarak yenilenen istek için yeni bir gözlemlenebilir akış oluşturur. Yenilemenin ardından orijinal isteği yeniden deneyerek yeni belirtecin uygulandığından emin olur. Durdurucu, eski gözlemlenebilirden yenisine geçiş yaparak token yenileme işlemini kesintisiz ve bloke edici olmayan bir şekilde gerçekleştirebilir. Bu teknik, gerçek zamanlı uygulamalarla çalışırken özellikle değerlidir çünkü kullanıcı etkileşimlerindeki kesintileri azaltırken güvenli kimlik doğrulamayı da korur. Örneğin, güvenli bir finansal kontrol paneline göz atan bir kullanıcı gereksiz yere yönlendirilmez veya oturumu kapatılmaz; bunun yerine yeni jeton alınır ve arka planda uygulanır. 🔄
Ayrıca BehaviorSubject yenileme sürecinin durumunu yöneterek çok önemli bir rol oynar. Bu RxJS yardımcı programı, yayınlanan son değeri koruyabilir; bu, özellikle birden fazla istek aynı anda 401 hatasıyla karşılaştığında faydalıdır. Birden fazla yenilemeyi tetiklemek yerine, durdurucu yalnızca bir jeton yenilemesini başlatır ve diğer tüm istekler bu tek jeton yenilemesini beklemek üzere sıraya alınır. BehaviorSubject'in switchMap ile kullanılması, bir isteğin yenilemeyi tetiklemesi durumunda, yeni belirtece ihtiyaç duyan diğer tüm isteklerin, tekrarlanan yenileme çağrılarına neden olmadan güncellenmiş kimlik bilgilerini kullanmasını sağlamaya yardımcı olur. Bu özellik, kullanıcıların birden fazla açık sekmeye sahip olabileceği veya uygulamanın aynı anda birden fazla ağ çağrısını yönettiği, dolayısıyla kaynaklardan tasarruf sağladığı ve aşırı sunucu yükünü önlediği durumlarda son derece faydalıdır.
Bu önleyici mantığının test edilmesi aynı zamanda farklı senaryolar altında çalışmasını sağlamak açısından da önemlidir; bu nedenle HttpTestingController'ı dahil ettik. Bu Angular test aracı, kontrollü bir ortamda 401 Yetkisiz durumu gibi HTTP yanıtlarını simüle etmemize ve test etmemize olanak tanır. Geliştiriciler, HttpTestingController tarafından sağlanan bir yöntem olan floş kullanarak gerçek dünyadaki hata yanıtlarını simüle edebilir ve önleyicinin beklendiği gibi davrandığını doğrulayabilir. Bu test yaklaşımı, uygulamayı dağıtmadan önce yenileme mantığının çeşitli durumları ne kadar iyi ele aldığını hassaslaştırmamıza olanak tanır. Bu yöntemlerle, önleyici yalnızca oturumu güvenli bir şekilde korumakla kalmıyor, aynı zamanda uygulamada gezinen kullanıcılara daha kesintisiz ve istikrarlı bir deneyim sunuyor. 👩💻
JWT Interceptor'ı Angular ile Uygulamak: Hata İşleme ve Token Yenileme Çözümü
Hata yönetimi ve oturum yönetimi için Angular'ı modüler hizmet yapısıyla kullanma
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse } from '@angular/common/http';
import { catchError, switchMap } from 'rxjs/operators';
import { Observable, throwError, BehaviorSubject } from 'rxjs';
import { AuthService } from './auth.service';
import { Router } from '@angular/router';
@Injectable()
export class JwtInterceptor implements HttpInterceptor {
private refreshTokenInProgress$ = new BehaviorSubject<boolean>(false);
constructor(private authService: AuthService, private router: Router) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
req = req.clone({ withCredentials: true });
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401) {
return this.handle401Error(req, next);
}
return throwError(() => error);
})
);
}
private handle401Error(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (!this.refreshTokenInProgress$.getValue()) {
this.refreshTokenInProgress$.next(true);
return this.authService.refreshToken().pipe(
switchMap(() => {
this.refreshTokenInProgress$.next(false);
return next.handle(req.clone({ withCredentials: true }));
}),
catchError((error) => {
this.refreshTokenInProgress$.next(false);
this.authService.logout();
this.router.navigate(['/login'], { queryParams: { returnUrl: req.url } });
return throwError(() => error);
})
);
}
return this.refreshTokenInProgress$.pipe(
switchMap(() => next.handle(req.clone({ withCredentials: true })))
);
}
}
JWT Interceptor Token Yenileme İşlemi için Açısal Birim Testi
Angular'ın önleyicisinde JWT yenilemeyi ve HTTP hata işlemeyi test etme
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { JwtInterceptor } from './jwt.interceptor';
import { HTTP_INTERCEPTORS, HttpClient } from '@angular/common/http';
import { AuthService } from './auth.service';
describe('JwtInterceptor', () => {
let httpMock: HttpTestingController;
let authServiceSpy: jasmine.SpyObj<AuthService>;
let httpClient: HttpClient;
beforeEach(() => {
authServiceSpy = jasmine.createSpyObj('AuthService', ['refreshToken', 'logout']);
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
JwtInterceptor,
{ provide: HTTP_INTERCEPTORS, useClass: JwtInterceptor, multi: true },
{ provide: AuthService, useValue: authServiceSpy }
]
});
httpMock = TestBed.inject(HttpTestingController);
httpClient = TestBed.inject(HttpClient);
});
afterEach(() => {
httpMock.verify();
});
it('should refresh token on 401 error and retry request', () => {
authServiceSpy.refreshToken.and.returnValue(of(true));
httpClient.get('/test').subscribe();
const req = httpMock.expectOne('/test');
req.flush(null, { status: 401, statusText: 'Unauthorized' });
expect(authServiceSpy.refreshToken).toHaveBeenCalled();
});
});
JWT Token Yenileme Stratejilerini Açısal Durdurucularla Genişletme
Açısal kullanmanın kritik bir yönü JWT token yakalayıcı Güvenli uygulamalar için kimlik doğrulama ve oturum sona erme yönetiminin karmaşıklığını verimli bir şekilde ele alıyor. Yalnızca 401 hatalarını yakalamanın ve belirteçleri yenilemenin ötesinde, çoklu isteği işleme ve belirteç yenilemelerinin nasıl optimize edileceğini düşünmek önemlidir. Birden fazla istek aynı anda 401 hatasıyla karşılaştığında, bir kuyruk veya kilitleme mekanizmasının uygulanması, aynı anda yalnızca bir belirteç yenilemesinin gerçekleşmesini sağlamak için son derece yararlı olabilir. Bu yaklaşım, gereksiz API çağrılarını önler ve özellikle yüksek trafikli uygulamalarda yükü azaltırken, sıraya alınmış tüm isteklerin yenileme sonrasında devam etmesine olanak tanır.
Angular'ın engelleyicileri aynı zamanda token depolama ve alımını nasıl ele aldığımızı kolaylaştırmamıza da olanak tanıyor. Yerel depolama alanında belirteçleri sabit kodlamak yerine Angular'ı kullanmak en iyisidir. HttpOnly çerezleri ve güvenliği artırmak için CSRF koruması. HttpOnly çerezleri sayesinde, JWT'ye JavaScript tarafından erişilemez veya değiştirilemez, bu da güvenliği büyük ölçüde artırır ancak yeni bir zorluk ekler: isteklerin yenilenen çerezi otomatik olarak almasının sağlanması. Angular'ın yerleşik yapısı withCredentials seçeneği, tarayıcıya bu çerezleri her isteğe dahil etmesi talimatını veren bir çözümdür.
Üretim ortamında, uygulamanın token yenilemeleriyle yük altında nasıl davrandığına ilişkin performans testlerinin çalıştırılması önerilir. Test kurulumları, yüksek talep hacimlerini simüle ederek önleyicinin mantığının verimli bir şekilde ölçeklenmesini sağlar. Uygulamada bu kurulum, kullanıcı deneyimini etkileyen jetonla ilgili hataların riskini en aza indirir. Durdurucu stratejisi, uygun çerez işleme ve testiyle eşleştirildiğinde, ister uygulama ister kritik finansal verileri yönetsin, ister bir sosyal platformun kullanıcı oturumlarını yönetsin, kesintisiz, kullanıcı dostu ve güvenli bir uygulamanın korunmasına yardımcı olur. 🌐🔐
Açısal Durdurucularla JWT Token Kullanımına İlişkin Yaygın Sorular
- Nasıl catchError JWT token kullanımı konusunda yardım ister misiniz?
- Kullanma catchError bir önleyici içindeki 401 hatalarını tanımlamamıza ve belirteçlerin süresi dolduğunda belirteç yenileme isteklerini sorunsuz bir şekilde tetiklememize olanak tanır.
- Neden BehaviorSubject yerine kullanılan Subject yenileme durumunu izlemek için?
- BehaviorSubject son yayılan değeri korur, bu da onu birden fazla yenileme çağrısını tetiklemeden eşzamanlı istekler arasında yenileme durumlarını yönetmek için kullanışlı hale getirir.
- Hangi rol switchMap HTTP isteklerini yeniden denemede oynamak ister misiniz?
- switchMap gözlemlenebilir belirteç yenilemesinden yeniden denenen HTTP isteğine geçiş yapılmasına olanak tanır ve yalnızca en son gözlemlenebilir tamamlamaların sağlanmasını sağlar.
- Durdurucuyu Angular'da nasıl test edebilirim?
- Açısal HttpTestingController önleyici mantığın doğru çalıştığını doğrulamak için 401 hataları da dahil olmak üzere HTTP yanıtlarını simüle etmek için kullanışlıdır.
- Neden kullanılmalı? withCredentials klonlanmış istekte?
- withCredentials flag, her isteğe güvenli HttpOnly çerezlerinin dahil edilmesini sağlar; bu, güvenli oturumların sürdürülmesi açısından önemlidir.
- Yoğun trafik altında token yenileme işlemini nasıl optimize edebilirim?
- Tek kullanmak BehaviorSubject veya kilitleme mekanizması, birden fazla yenileme isteğinin engellenmesine yardımcı olarak trafiğin yoğun olduğu senaryolarda performansı artırır.
- Durdurucu, oturum sona erdiğinde kullanıcı deneyimini nasıl etkiler?
- Durdurucu, otomatik oturum yenilemeyi etkinleştirir, böylece kullanıcılar beklenmedik bir şekilde oturumdan çıkmaz ve daha sorunsuz bir kullanıcı deneyimine olanak tanır.
- Nasıl clone istekleri değiştirme konusunda yardım?
- clone isteğin, ayar gibi değiştirilmiş özelliklere sahip bir kopyasını oluşturur withCredentials, orijinal isteği değiştirmeden.
- Durdurucu birden fazla kullanıcı oturumuyla çalışıyor mu?
- Evet, ancak her oturumun JWT'sini bağımsız olarak yönetmesi veya yenileme mantığının birden fazla oturuma uyarlanması gerekir.
- Durdurucu 401 dışı hataları işleyebilir mi?
- Evet, önleyici 403 Yasak gibi diğer hataları yakalayacak ve daha iyi bir kullanıcı deneyimi için bunları uygun şekilde işleyecek şekilde genişletilebilir.
Açısal Uygulamalarda JWT Token Yenilemesini Kolaylaştırma
Etkili JWT token yönetimi, Angular uygulamalarında hem kullanıcı deneyimini hem de güvenliği geliştirmek için çok önemlidir. 401 hatalarını yakalayacak ve otomatik olarak belirteç yenilemeyi başlatacak bir önleyici uygulayarak, zorunlu oturum kapatmaları önleyebilir ve kesintisiz bir kullanıcı akışı sağlayabilirsiniz. Ek olarak, yenileme sırasında eşzamanlı isteklerin işlenmesi DavranışKonu, kaynak kullanımını optimize ederek yalnızca bir yenileme çağrısı yapılmasını sağlar.
Sonuçta amaç, güvenlik ve kullanıcı rahatlığı arasında bir denge kurmaktır. Durdurucu mantığını gerçek dünya senaryoları için düzenli olarak test etmek ve iyileştirmek, uygulamanızın yüksek hacimli istekleri sorunsuz bir şekilde işlemesine olanak tanır. Belirteç yönetiminde en iyi uygulamaları benimsemek, oturumlar arasında güvenli, kullanıcı dostu bir deneyimin korunmasına yardımcı olabilir. 👨💻
JWT Interceptor Uygulaması için Referanslar ve Kaynaklar
- Angular'da HTTP önleyicileri oluşturmaya ilişkin ayrıntılı bilgi resmi Angular belgelerinde bulunabilir: Açısal HTTP Kılavuzu .
- JWT belirteci yenileme mekanizmalarını ve en iyi uygulamaları yönetmeye ilişkin bilgiler için bkz. Auth0'ın Jeton Yenileme Kılavuzu .
- RxJS kütüphanesi, bu makalede kullanılan operatörler hakkında kapsamlı ayrıntılar sunmaktadır. SwitchMap Ve yakalama hatası: RxJS Operatör Kılavuzu .
- Açısal test stratejileri için HttpTestingController, Angular'ın test yardımcı programlarındaki kaynakları kontrol edin: Açısal HTTP Test Kılavuzu .