在 Angular 7 中使用 keycloak 时如何保持会话活动?
How to keep session active while using keycloak in Angular 7?
我在 Angular 7 项目中使用此插件 https://github.com/mauriciovigolo/keycloak-angular。
版本:
keycloak-angular : 6.1.0
angular : 7.1.4
登录成功后,这是我从/protocol/openid-connect/token
得到的回复:
expires_in : 1980
refresh_expires_in : 1800
它会在 30 分钟后自动注销用户并重定向到登录页面。这种行为很烦人。只要用户与应用程序交互,我希望它表现得好像什么都没发生一样。换句话说,不要在 30 分钟后自动注销,它应该保持会话活动。
有人可以指导我实现这一目标需要哪些具体步骤吗?
编辑 1
正如@thijsfranck 在他的回答中所建议的那样,我修改了代码,并且成功了。
app-init.ts
import {KeycloakService} from 'keycloak-angular';
export function initializer(keycloak: KeycloakService) {
return () => {
return new Promise(async (resolve, reject) => {
try {
const _REALM = "realm";
const _URL = "http://example.com";
const _CLIENT_ID = "id"
await keycloak.init({
config: {
realm: _REALM,
url: _URL,
clientId: _CLIENT_ID,
},
initOptions: {
onLoad: 'login-required',
checkLoginIframe: false
},
enableBearerInterceptor: true,
bearerExcludedUrls: ['/assets', '/clients/public']
})
const keycloakAuth = keycloak.getKeycloakInstance();
const updateToken = async (): Promise < string > => {
const {success,error} = keycloakAuth.updateToken(5);
return new Promise < string > ((res, rej) => {
success(() => res(keycloakAuth.token));
error(rej);
});
}
const login = async (): Promise < void > => {
const {success,error} = keycloakAuth.login();
return new Promise < void > ((res2, rej2) => {
success(res2);
error(rej2);
});
}
keycloakAuth.onTokenExpired = () => {
if (keycloakAuth.refreshToken) {
updateToken();
} else {
login();
}
}
resolve();
} catch (error) {
reject(error);
}
});
};
}
这里是app.module.ts
providers: [
{
provide: APP_INITIALIZER,
useFactory: initializer,
multi: true,
deps: [KeycloakService]
}
]
当您的授权令牌过期时,您可以使用刷新令牌(如果您有有效令牌)来检索新令牌。
请参阅下面的代码片段。我没有具体使用 keycloak-angular
,但是 keycloak-js
(您的图书馆也使用它)会在您的身份验证令牌过期时发出一个名为 onTokenExpired
的事件。您可以使用该事件来触发令牌刷新。如果我正确阅读文档,您应该可以访问 initializer()
函数中的 keycloakAuth
对象。
import Keycloak from 'keycloak-js';
private keycloakAuth: Keycloak.KeycloakInstance;
/**
* Whenever the token expires and a refresh token is available, try to refresh the access token.
* Otherwise, redirect to login.
*/
this.keycloakAuth.onTokenExpired = () => {
if (this.keycloakAuth.refreshToken) {
this.updateToken();
} else {
this.login();
}
};
async updateToken(): Promise<string> {
const { success, error } = this.keycloakAuth.updateToken(5);
return new Promise<string>((resolve, reject) => {
success(() => resolve(this.keycloakAuth.token));
error(reject);
});
}
async login(): Promise<void> {
const { success, error } = this.keycloakAuth.login();
return new Promise<void>((resolve, reject) => {
success(resolve);
error(reject);
});
}
我在 Angular 7 项目中使用此插件 https://github.com/mauriciovigolo/keycloak-angular。
版本:
keycloak-angular : 6.1.0
angular : 7.1.4
登录成功后,这是我从/protocol/openid-connect/token
得到的回复:
expires_in : 1980
refresh_expires_in : 1800
它会在 30 分钟后自动注销用户并重定向到登录页面。这种行为很烦人。只要用户与应用程序交互,我希望它表现得好像什么都没发生一样。换句话说,不要在 30 分钟后自动注销,它应该保持会话活动。
有人可以指导我实现这一目标需要哪些具体步骤吗?
编辑 1
正如@thijsfranck 在他的回答中所建议的那样,我修改了代码,并且成功了。
app-init.ts
import {KeycloakService} from 'keycloak-angular';
export function initializer(keycloak: KeycloakService) {
return () => {
return new Promise(async (resolve, reject) => {
try {
const _REALM = "realm";
const _URL = "http://example.com";
const _CLIENT_ID = "id"
await keycloak.init({
config: {
realm: _REALM,
url: _URL,
clientId: _CLIENT_ID,
},
initOptions: {
onLoad: 'login-required',
checkLoginIframe: false
},
enableBearerInterceptor: true,
bearerExcludedUrls: ['/assets', '/clients/public']
})
const keycloakAuth = keycloak.getKeycloakInstance();
const updateToken = async (): Promise < string > => {
const {success,error} = keycloakAuth.updateToken(5);
return new Promise < string > ((res, rej) => {
success(() => res(keycloakAuth.token));
error(rej);
});
}
const login = async (): Promise < void > => {
const {success,error} = keycloakAuth.login();
return new Promise < void > ((res2, rej2) => {
success(res2);
error(rej2);
});
}
keycloakAuth.onTokenExpired = () => {
if (keycloakAuth.refreshToken) {
updateToken();
} else {
login();
}
}
resolve();
} catch (error) {
reject(error);
}
});
};
}
这里是app.module.ts
providers: [
{
provide: APP_INITIALIZER,
useFactory: initializer,
multi: true,
deps: [KeycloakService]
}
]
当您的授权令牌过期时,您可以使用刷新令牌(如果您有有效令牌)来检索新令牌。
请参阅下面的代码片段。我没有具体使用 keycloak-angular
,但是 keycloak-js
(您的图书馆也使用它)会在您的身份验证令牌过期时发出一个名为 onTokenExpired
的事件。您可以使用该事件来触发令牌刷新。如果我正确阅读文档,您应该可以访问 initializer()
函数中的 keycloakAuth
对象。
import Keycloak from 'keycloak-js';
private keycloakAuth: Keycloak.KeycloakInstance;
/**
* Whenever the token expires and a refresh token is available, try to refresh the access token.
* Otherwise, redirect to login.
*/
this.keycloakAuth.onTokenExpired = () => {
if (this.keycloakAuth.refreshToken) {
this.updateToken();
} else {
this.login();
}
};
async updateToken(): Promise<string> {
const { success, error } = this.keycloakAuth.updateToken(5);
return new Promise<string>((resolve, reject) => {
success(() => resolve(this.keycloakAuth.token));
error(reject);
});
}
async login(): Promise<void> {
const { success, error } = this.keycloakAuth.login();
return new Promise<void>((resolve, reject) => {
success(resolve);
error(reject);
});
}