py-learn / src /app /authentication /authentication.service.ts
Oviya
Deploy Angular to HF Space
e4ab6d0
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/internal/Observable';
import { tap } from 'rxjs/operators';
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
private apiUrl = 'http://127.0.0.1:5000'; // Your backend URL
private loggedInSubject = new BehaviorSubject<boolean>(this.isLoggedIn()); // BehaviorSubject to track login status
constructor(private http: HttpClient) {
// Change from 5 minutes to 30 seconds
setInterval(() => this.checkAndRefreshToken(), 30 * 1000); // Every 30 seconds
// Periodically check for token expiry and refresh it if necessary
//setInterval(() => this.checkAndRefreshToken(), 5 * 60 * 1000); // Check every 5 minutes
}
// βœ… Login Method
// βœ… Login Method (returns an Observable)
login(username: string, password: string): Observable<any> {
const loginData = { username, password };
return this.http.post(`${this.apiUrl}/login`, loginData).pipe(
tap((response: any) => {
//const now = new Date();
// Store tokens in localStorage
localStorage.setItem('access_token', response.access_token);
localStorage.setItem('refresh_token', response.refresh_token);
// Optionally store expiry time of the access token (2 minutes)
const accessTokenExpiry = Date.now() + 2 * 60 * 1000; // 2 minutes expiration for access token
localStorage.setItem('access_token_expiry', accessTokenExpiry.toString());
// Optionally store expiry time of the refresh token (5 minutes)
const refreshTokenExpiry = Date.now() + 10 * 60 * 1000; // 5 minutes expiration for refresh token
localStorage.setItem('refresh_token_expiry', refreshTokenExpiry.toString());
this.loggedInSubject.next(true);
}),
catchError(error => {
// Handle error (token expiry / invalid login)
if (error.status === 401 && error.error.message === 'Token has expired') {
//alert('Your session has expired, please log in again.');
}
return throwError(error);
})
);
}
logout(): Observable<any> {
const token = this.getToken();
console.log('πŸ”‘ Token at logout start:', token);
this.removeToken(); // Remove token first
this.loggedInSubject.next(false);
if (!token) {
console.warn('⚠️ No token found. Emitting success anyway.');
return new Observable(observer => {
observer.next(true);
observer.complete();
});
}
const headers = new HttpHeaders().set('Authorization', `Bearer ${token}`);
console.log('πŸ“€ Sending logout request with headers:', headers);
return this.http.post(`${this.apiUrl}/logout`, {}, { headers }).pipe(
tap(() => {
console.log('βœ… Logout API request completed'); // This should now appear
}),
catchError((error) => {
console.error('❌ Logout error in service:', error);
return new Observable(observer => {
observer.next(true); // Continue flow even on error
observer.complete();
});
})
);
}
// βœ… Get Token (to use for making authorized requests)
getToken(): string | null {
return localStorage.getItem('access_token');
}
// βœ… Store Token
storeToken(token: string): void {
localStorage.setItem('access_token', token);
console.log('Token stored:', token); // Log the token to confirm it's saved
this.loggedInSubject.next(true); // Update login status
}
// βœ… Remove Token
removeToken(): void {
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
localStorage.removeItem('access_token_expiry');
this.loggedInSubject.next(false); // Update login status
}
// βœ… Check if the user is logged in
isLoggedIn(): boolean {
return !!this.getToken();
}
// βœ… Observable to track login status
get isLoggedIn$(): Observable<boolean> {
return this.loggedInSubject.asObservable();
}
checkAndRefreshToken() {
const accessTokenExpiry = localStorage.getItem('access_token_expiry');
if (accessTokenExpiry && Date.now() >= (+accessTokenExpiry - 5000)) {
// Refresh 5 seconds before expiry
this.refreshAccessToken();
}
}
// Check token every 5 minutes
// βœ… Refresh Access Token Method
// βœ… Refresh Access Token Method
//refreshAccessToken() {
// const refreshToken = localStorage.getItem('refresh_token');
// if (refreshToken) {
// this.http.post(`${this.apiUrl}/refresh`, { refresh_token: refreshToken }).subscribe((response: any) => {
// // Store the new access token
// localStorage.setItem('access_token', response.access_token);
// // Optionally, update the expiry time of the new access token (2 minutes)
// const newAccessTokenExpiry = Date.now() + 2 * 60 * 1000; // 2 minutes
// localStorage.setItem('access_token_expiry', newAccessTokenExpiry.toString());
// alert('Your access token has been refreshed successfully!');
// }, error => {
// console.log("Error refreshing token", error);
// // Handle token refresh failure (e.g., log out the user)
// this.logout();
// });
// }
//}
refreshAccessToken() {
const refreshToken = localStorage.getItem('refresh_token');
if (refreshToken) {
this.http.post(`${this.apiUrl}/refresh`, { refresh_token: refreshToken }).subscribe(
(response: any) => {
// Store the new access token
localStorage.setItem('access_token', response.access_token);
// Update expiry
const newAccessTokenExpiry = Date.now() + 2 * 60 * 1000; // 2 minutes
localStorage.setItem('access_token_expiry', newAccessTokenExpiry.toString());
//alert('Your access token has been refreshed successfully!');
},
error => {
console.log("Error refreshing token", error);
if (
error.status === 401 &&
(error.error.message === 'Refresh token has expired' || error.error.message === 'Invalid refresh token')
) {
//alert('Your session has expired. Please log in again.');
// βœ… Remove tokens and redirect to login
this.removeToken();
this.loggedInSubject.next(false);
window.location.href = '/authentication'; // Adjust this if your login route is different
} else {
// Other errors can be handled differently
console.error("Unexpected error:", error);
}
}
);
}
}
}