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