I am using angular and asp.net core I have implemented JWT Token and refresh token with the help of
this artical I have written code to check Jwt is valid in Authguard if jwt is not valid so with refresh token will make call to api and get the new Jwt and refresh token . this scenario is happing only if I am performing any event like refreshing page and navigating to another page. I want to know is there any way that if our jwt token expire without performing any event angular detect it and automatically call to api with refersh token and get the new jwt token
here are codes
authguard
here in authguard isUserAuthenticated() is going to check jwt expired or not if expired it will make api call with refresh token and get the new jwt and refresh token
async canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Promise<boolean> {
if((await this._authService.isUserAuthenticated()) === true){
return true;
}
else{
this._router.navigate([RouteConstant.SIGN_IN]);
return false;
}
}
public async isUserAuthenticated(){
if(this._storageService.getToken() !== null){
if(!this._jwtHelperService.isTokenExpired(this._storageService.getToken()?.toString())){
return true;
}
else{
if(!this._storageService.refreshTokenExists()){
return false;
}
else{
let authTokenClient: AuthTokenClient = {
token: this._storageService.getToken() as string,
refreshToken: this._storageService.getRefreshToken() as string
};
let response: AuthToken = await this._serverService.refreshAuthToken(authTokenClient).toPromise<AuthToken>();
console.log(response);
this.setAuth(response);
return !this._jwtHelperService.isTokenExpired(this._storageService.getToken()?.toString());
}
}
}
else{
return false;
}
}
}
public setAuth(authToken: AuthToken){
this._storageService.saveToken(authToken.token?.toString());
this._storageService.saveRefreshToken(authToken.refreshToken);
}
public async refreshAuthToken(authTokenClient: AuthTokenClient) {
const response = await this._http.post<AuthToken>(environment.apiHost + UrlConstant.ACCOUNT_REFRESH, authTokenClient,{observe: 'response'}).toPromise();
console.log(response);
const newToken = (<any>response).body.token;
console.log(newToken);
const newRefreshToken = (<any>response).body.refreshToken;
console.log(newRefreshToken);
localStorage.setItem("token", newToken);
localStorage.setItem("refreshToken",newRefreshToken);
if (newToken && newRefreshToken == null){
return false
}
else {
return true;
}
}
Startup.cs
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtSettings.ValidIssuer,
ValidAudience = jwtSettings.ValidAudience,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration[ConfigurationKeyConstant.JWT_SECRET_KEY])),
ClockSkew = TimeSpan.Zero
};
});
Controller.cs
[Route("refresh")]
public IActionResult Refresh(AuthTokenBase authTokenBase)
{
if (authTokenBase is null)
{
return BadRequest("Invalid client request");
}
string accessToken = authTokenBase.Token;
string refreshToken = authTokenBase.RefreshToken;
var principal = this._jwtHandler.GetPrincipalFromExpiredToken(accessToken);
var username = principal.Identity.Name;
string newAccessToken = this._jwtHandler.GenerateToken();
string newRefreshToken = this._jwtHandler.GenerateRefreshToken();
return Ok(new AuthToken()
{
Token = newAccessToken,
RefreshToken = newRefreshToken,
IsAuthSuccessful = true
});
}
import { interval, Observable, Subscription } from "rxjs"; timer: any; constructor(private _authservice: AuthService, private _storageService: StorageService) { } ngOnInit() { this.timer = interval(60000).subscribe(x => { this._authservice.isUserAuthenticated(); });is this right way ?? - Shivam DubeyClockSkew=TimeSpan.Zeroin Startup.cs => Configure in asp.net-core so even after my token will expire server will allow that till 5 minutes which is defaultClockSkew. As I am keeping my JWT token expiry time for 5 minutes and keeping time-interval to check validity is 4 minutes .So I think in this way my call will always success - Shivam Dubey