TypeScript - Angular 6'da Jwt token süresi
Jwt kullanarak veritabanı çağrılarını doğrulayan bir Angular uygulaması yapıyorum. Ancak sorun, sunucuda token süresi dolduğunda, token hâlâ yerel depolamada bulunduğu için uygulamanın veri yerine boş sayfalar göstermeye başlaması. Biraz araştırmadan sonra, token süresini takip etmek için jwt2 kütüphanesinin kullanılabileceğini öğrendim. Ancak bunu kullandıktan sonra bile, giriş sayfasına yönlendirilmek için sayfayı yenilemem gerekiyor. Hâlâ bileşenler arasında hareket edebiliyorum. İstediğim, token süresi dolar dolmaz giriş sayfasının gelmesi veya tokenin yenilenmesi ve bileşenler arasında hareket ederken bile, token süresi dolmuşsa kullanıcının giriş sayfasına yönlendirilmesi veya tokenin yenilenmesi. Başka ne yapmam gerektiğini bilmiyorum. Lütfen yardım edin. Şimdiden teşekkürler.
İşte benim kimlik doğrulama korumam:
Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router,private authService:AuthService ){ }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if (!(this.authService.isTokenExpired()) ){
// logged in so return true
console.log("Logged IN");
return true;
}
// not logged in so redirect to login page with the return url
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
return true;
}
}
İşte benim kimlik doğrulama servisım:
const helper = new JwtHelperService();
@Injectable({
providedIn: 'root'
})
export class AuthService {
constructor(private http: HttpClient) { }
/* public login<T>(username: string, password: string): Observable<HttpResponse<T>> {
let headers = new HttpHeaders();
const clientId = 'rosClient';
const secret = 'secret';
headers = headers.append("Authorization", "Basic " + btoa(`${username}:${password}`));
headers = headers.append("Content-Type", "application/x-www-form-urlencoded");
return this.http.get<T>('/auth/login', {
headers: headers,
observe: 'response'
});
}*/
public login<T>(username: string, password: string): Observable<HttpResponse<T>> {
let headers = new HttpHeaders();
const clientId = 'clientid';
const secret = 'secret';
headers = headers.append('Authorization', 'Basic ' + btoa(`${clientId}:${secret}`));
headers = headers.append('Content-Type', 'application/x-www-form-urlencoded');
const params = new HttpParams().set('username', username).set('password', password).set('grant_type', 'password').set('scope', 'read');
return this.http.post<T>('/oauth/token', params.toString(), {
headers,
observe: 'response'
});
}
public logout<T>() {
this.http.post('/oauth/revoke_token', '', {}).subscribe();
}
getToken(): string {
return localStorage.getItem(TOKEN_NAME);
}
isTokenExpired(token?: string): boolean {
if(!token) token = this.getToken();
if(!token) return true;
const date = helper.getTokenExpirationDate(token);
console.log(date);
if(date === undefined) return false;
return !(date.valueOf() > new Date().valueOf());
}
}
Aşağıda hata yakalayıcım var:
@Injectable()
export class H401Interceptor implements HttpInterceptor {
constructor(private authService: AuthService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError(err => {
if (err.status === 401) {
// auto logout if 401 response returned from api
// this.authService.logout();
// location.reload(true);
localStorage.removeItem('currentUser');
}
const error = err.error.message || err.statusText;
return throwError(error);
}));
}
}
Cevap #1
HttpInterceptor kullanabilirsiniz, backend '401 Yetkisiz' yanıtı verdiğinde, token'ı silersiniz ve giriş sayfasına yönlendirirsiniz. İşte çalışan bir kod:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.storageService.retrieve(tokenKey)}`,
'Content-Type': 'application/json'
}
});
return next.handle(request).pipe(
catchError(
(err, caught) => {
if (err.status === 401){
this.handleAuthError();
return of(err);
}
throw err;
}
)
);
}
private handleAuthError() {
this.storageService.delete(tokenKey);
this.router.navigateByUrl('signIn');
}
