Skip to content

Commit a89f3a2

Browse files
Make final changes for code flow with silent refresh
Fixes #24
1 parent aa3ea01 commit a89f3a2

File tree

3 files changed

+31
-29
lines changed

3 files changed

+31
-29
lines changed

src/app/core/auth-config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const authConfig: AuthConfig = {
77
redirectUri: window.location.origin + '/index.html',
88
silentRefreshRedirectUri: window.location.origin + '/silent-refresh.html',
99
scope: 'openid profile email api', // Ask offline_access to support refresh token refreshes
10+
useSilentRefresh: true,
1011
silentRefreshTimeout: 5000, // For faster testing
1112
timeoutFactor: 0.25, // For faster testing
1213
sessionChecksEnabled: true,

src/app/core/auth.service.ts

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Injectable } from '@angular/core';
22
import { Router } from '@angular/router';
3-
import { OAuthErrorEvent, OAuthService, OAuthEvent, TokenResponse } from 'angular-oauth2-oidc';
3+
import { OAuthErrorEvent, OAuthService } from 'angular-oauth2-oidc';
44
import { BehaviorSubject, combineLatest, Observable, ReplaySubject } from 'rxjs';
55
import { filter, map } from 'rxjs/operators';
66

@@ -106,7 +106,7 @@ export class AuthService {
106106
// 2. SILENT LOGIN:
107107
// Try to log in via a refresh because then we can prevent
108108
// needing to redirect the user:
109-
return this.tryNoPromptRefresh()
109+
return this.oauthService.silentRefresh()
110110
.then(() => Promise.resolve())
111111
.catch(result => {
112112
// Subset of situations from https://openid.net/specs/openid-connect-core-1_0.html#AuthError
@@ -160,24 +160,14 @@ export class AuthService {
160160
.catch(() => this.isDoneLoadingSubject$.next(true));
161161
}
162162

163-
private tryNoPromptRefresh(): Promise<TokenResponse | OAuthEvent> {
164-
if (this.oauthService.getRefreshToken()) {
165-
console.log('Found a refresh token, trying to use it.');
166-
return this.oauthService.refreshToken();
167-
}
168-
169-
console.log('Found no refresh token, trying iframe based refresh');
170-
return this.oauthService.silentRefresh();
171-
}
172-
173163
public login(targetUrl?: string) {
174164
// Note: before version 9.1.0 of the library you needed to
175165
// call encodeURIComponent on the argument to the method.
176166
this.oauthService.initLoginFlow(targetUrl || this.router.url);
177167
}
178168

179169
public logout() { this.oauthService.logOut(); }
180-
public refresh() { this.tryNoPromptRefresh(); }
170+
public refresh() { this.oauthService.silentRefresh(); }
181171
public hasValidToken() { return this.oauthService.hasValidAccessToken(); }
182172

183173
// These normally won't be exposed from a service like this, but

src/silent-refresh.html

+27-16
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
1-
<!doctype html>
21
<html>
2+
33
<body>
4-
<script>
5-
console.log("The silent-refresh.html file was loaded and now posting to the parent.");
6-
7-
// For code flow with IdentityServer4 the redirect will contain the new code in
8-
// the location.search. However, the oauth library expects it in the hash fragment
9-
// so we need to "fake" that.
10-
//
11-
// We can't just set `silentRefreshMessagePrefix` on AuthConfig, because the normal
12-
// redirect after interactive login *does* use the hash fragment, so we'd break that.
13-
//
14-
// See also: https://github.com/manfredsteyer/angular-oauth2-oidc/issues/777
15-
const fakeHashFragment = location.search.replace(/^\?/, "#");
16-
17-
parent.postMessage(fakeHashFragment, location.origin);
18-
</script>
4+
<script>
5+
// Based on: https://manfredsteyer.github.io/angular-oauth2-oidc/docs/additional-documentation/silent-refresh.html
6+
7+
const checks = [/[\?|&|#]code=/, /[\?|&|#]error=/, /[\?|&|#]token=/, /[\?|&|#]id_token=/];
8+
9+
function isResponse(str) {
10+
let count = 0;
11+
12+
if (!str) {
13+
return false;
14+
}
15+
16+
for (let i = 0; i < checks.length; i++) {
17+
if (str.match(checks[i])) return true;
18+
}
19+
20+
return false;
21+
}
22+
23+
let message = isResponse(location.hash) ? location.hash : '#' + location.search;
24+
25+
console.log("Silent refresh iframe is posting to the parent application, message:", message);
26+
27+
(window.opener || window.parent).postMessage(message, location.origin);
28+
</script>
1929
</body>
30+
2031
</html>

0 commit comments

Comments
 (0)