This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @NgModule({ | |
| declarations: [], | |
| imports: [CommonModule], | |
| providers: [ | |
| { | |
| provide: APP_INITIALIZER, | |
| useFactory: appInitializer, | |
| multi: true, | |
| deps: [AuthService], | |
| }, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| export function appInitializer(authService: AuthService) { | |
| return () => | |
| new Promise((resolve) => { | |
| console.log('refresh token on app start up') | |
| authService.refreshToken().subscribe().add(resolve); | |
| }); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @Injectable() | |
| export class JwtInterceptor implements HttpInterceptor { | |
| constructor(private authService: AuthService) {} | |
| intercept( | |
| request: HttpRequest<unknown>, | |
| next: HttpHandler | |
| ): Observable<HttpEvent<unknown>> { | |
| // add JWT auth header if a user is logged in for API requests | |
| const accessToken = localStorage.getItem('access_token'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const routes: Routes = [ | |
| // ... | |
| { path: 'demo-apis', component: DemoApisComponent, canActivate: [AuthGuard] }, | |
| ]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @Injectable({ | |
| providedIn: 'root', | |
| }) | |
| export class AuthGuard implements CanActivate { | |
| constructor(private router: Router, private authService: AuthService) {} | |
| canActivate( | |
| next: ActivatedRouteSnapshot, | |
| state: RouterStateSnapshot | |
| ): |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| private storageEventListener(event: StorageEvent) { | |
| if (event.storageArea === localStorage) { | |
| if (event.key === 'logout-event') { | |
| this._user.next(null); | |
| } | |
| if (event.key === 'login-event') { | |
| location.reload(); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @Injectable({ | |
| providedIn: 'root', | |
| }) | |
| export class AuthService implements OnDestroy { | |
| private readonly apiUrl = `${environment.apiUrl}api/account`; | |
| private timer: Subscription; | |
| private _user = new BehaviorSubject<ApplicationUser>(null); | |
| user$: Observable<ApplicationUser> = this._user.asObservable(); | |
| private storageEventListener(event: StorageEvent) { // ... } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public JwtAuthResult Refresh(string refreshToken, string accessToken, DateTime now) | |
| { | |
| var (principal, jwtToken) = DecodeJwtToken(accessToken); | |
| if (jwtToken == null || !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature)) | |
| { | |
| throw new SecurityTokenException("Invalid token"); | |
| } | |
| var userName = principal.Identity.Name; | |
| if (!_usersRefreshTokens.TryGetValue(refreshToken, out var existingRefreshToken)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [HttpPost("refresh-token")] | |
| [Authorize] | |
| public async Task<ActionResult> RefreshToken([FromBody] RefreshTokenRequest request) | |
| { | |
| try | |
| { | |
| var userName = User.Identity.Name; | |
| _logger.LogInformation($"User [{userName}] is trying to refresh JWT token."); | |
| if (string.IsNullOrWhiteSpace(request.RefreshToken)) |
NewerOlder