Я использовал токены jwt для моего проекта angular 6 с Web API.Я могу войти в свою сессию, генерируя токен, но когда он истекает, скажем, через 10 минут.Я хочу показать всплывающее окно, которое скажет, что ваша сессия истекла, пожалуйста, нажмите ниже, чтобы обновить вашу сессию.Это создаст новый токен, который можно использовать для доступа к моему порталу.
Я попробовал следующий код, используя несколько ссылок ниже
https://steemit.com/utopian-io/@babelek/how-to-manage-with-refresh-token-in-asp-net-core-2-0-web-api
http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/
Обновить токен (JWT) в перехватчикеAngular 6
В моем файле аутентификации Interceptor в файле angular 6. Я добавил код, как показано ниже
intercept(req: HttpRequest<any>, next: HttpHandler) {
const token = sessionStorage.getItem('token');
const authReq = req.clone({ setHeaders: { Authorization: 'bearer ' +
token } });
return next.handle(authReq).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// if the token is valid
}
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
const refreshToken =
sessionStorage.getItem('refreshToken');
this.loginService.refreshToken([refreshToken]).subscribe((res: any) => {
const tokenInfo =
this.loginService.getDecodedAccessToken(res.access_token);
const loggedUser = tokenInfo.userName;
this.loginService.setToken(res.access_token,
loggedUser, res.refresh_token);
sessionStorage.setItem('userName', loggedUser);
}, error => {
});
this.router.navigateByUrl('/login');
this.authService.collectFailedRequest(authReq);
}
}
});
}
В моем файле службы входа в систему я добавил код ниже
public getToken(parameter: string[]): Observable<any> {
const data = new HttpParams()
.set('username', parameter[0])
.set('password', parameter[1])
.set('grant_type', 'password');
const url = this.API_URL + '/api/confirm_login';
return this._httpClient.post(url, data.toString()).pipe(
map(x => x),
catchError((error: any) => {
let errorMessage: any;
if (error.error && error.error.error_description) {
errorMessage = error.error.error_description;
}
throw errorMessage;
})
);
}
public refreshToken(parameter: string[]): Observable<any> {
const data = new HttpParams()
.set('refresh_token', parameter[0])
.set('grant_type', 'refresh_token');
const url = this.API_URL + '/api/refresh_token';
return this._httpClient.post(url, data.toString()).pipe(map(x => x),
catchError((error: any) => {
let errorMessage: any;
if (error.error && error.error.error_description) {
errorMessage = error.error.error_description;
}
throw errorMessage;
})
);
}
public setToken(token: any, getLoggedUser: any, refresh_token: any) {
sessionStorage.setItem('token', token);
sessionStorage.setItem('userName', getLoggedUser);
sessionStorage.setItem('refreshToken', refresh_token);
}
getDecodedAccessToken(token: string): any {
try {
return jwt_decode(token);
} catch (Error) {
return null;
}
}
В моем файле authservice я добавил
authenticated(): boolean {
const token = sessionStorage.getItem('token');
if (!token) {
return null;
}
return !this.jwtHelper.isTokenExpired(token);
}
В моем файле startup.cs я добавил
public void ConfigureOAuth(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
OAuthAuthorizationServerOptions OAuthServerOptions = new
OAuthAuthorizationServerOptions()
{
AllowInsecureHttp = true,
TokenEndpointPath = new PathString("/api/confirm_login"),
AccessTokenExpireTimeSpan = TimeSpan.FromMilliseconds(30000),
Provider = new ldAuthorizationServerProvider(),
AccessTokenFormat = new
ldTokenFormat(ConfigurationManager.AppSettings["as:AngularHostURL"]),
RefreshTokenProvider = new RefreshTokenProvider(),
AuthorizeEndpointPath = new PathString("/api/refresh_token"),
};
app.UseOAuthAuthorizationServer(OAuthServerOptions);
}
Это мой refreshtokenprovider
public class RefreshTokenProvider : IAuthenticationTokenProvider
{
private static ConcurrentDictionary<string, AuthenticationTicket>
_refreshTokens = new ConcurrentDictionary<string, AuthenticationTicket>();
public async Task CreateAsync(AuthenticationTokenCreateContext
context)
{
var guid = Guid.NewGuid().ToString();
// copy all properties and set the desired lifetime of refresh
token
var refreshTokenProperties = new
AuthenticationProperties(context.Ticket.Properties.Dictionary)
{
IssuedUtc = context.Ticket.Properties.IssuedUtc,
ExpiresUtc =
DateTime.UtcNow.AddMilliseconds(30000)//DateTime.UtcNow.AddYears(1)
};
var refreshTokenTicket = new
AuthenticationTicket(context.Ticket.Identity, refreshTokenProperties);
_refreshTokens.TryAdd(guid, refreshTokenTicket);
// consider storing only the hash of the handle
context.SetToken(guid);
}
public void Create(AuthenticationTokenCreateContext context)
{
throw new NotImplementedException();
}
public void Receive(AuthenticationTokenReceiveContext context)
{
throw new NotImplementedException();
}
public async Task ReceiveAsync(AuthenticationTokenReceiveContext context)
{
Guid token;
if (Guid.TryParse(context.Token, out token))
{
AuthenticationTicket ticket;
if (_refreshTokens.TryRemove(token, out ticket))
{
context.SetTicket(ticket);
}
}
}
Здесь мой код не доходит до метода GrantRefreshToken.Я не уверен, что мне не хватает.
Любая помощь приветствуется