Ионный перехватчик, использующий токены обновления с использованием асинхронного хранилища sqLite
Я успешно разработал перехватчик angular2, использующий токены обновления (обновляющий токен и затем повторяющий запрос http), в котором access_token и refresh_token оба хранятся в localStorage.
Ниже приведен код для обновления токена в моем "AuthService":
refreshToken():Observable<Response>
{
let refToken: string = localStorage.getItem("bdRefreshToken");
let username: string = localStorage.getItem("bdUsername");
let body = "grant_type=refresh_token"
+"&client_id=" + Settings.loginInfo.client_id
+"&client_secret=" + Settings.loginInfo.client_secret
+"&scope=" + Settings.loginInfo.scope
+"&username="+username
+"&refresh_token="+refToken;
let header = new Headers({
'Content-Type': 'application/x-www-form-urlencoded'
});
let ro:RequestOptions = new RequestOptions({
headers: header
});
return this._http.post(Settings.tokenEndpoint, body, ro)
//.map(res => res.json())
.map(data => {
let d = data.json();
localStorage.setItem('bdAccessToken', d.access_token);
localStorage.setItem('bdRefreshToken', d.refresh_token);
this.saveRoles(d.access_token);
return data;
}
)
.catch(error => {
this.logout();
return Observable.throw(error)
});
}
И следующее является частью моего унаследованного http-класса, который служит перехватчиком:
get(url:string, options?:RequestOptions):Observable<Response>
{
return super.get(url, this.getAuthorizedOptions())
.catch(err => {
if (err && err.status === 401){
return this._authService.refreshToken()
.flatMap(r =>
super.get(url, this.getAuthorizedOptions())
)
.catch(err2 => {
this.redirect();
return Observable.throw(err2);
});
}
else {
return Observable.throw(err);
}
});
}
private getAuthorizedOptions():RequestOptions
{
let token = localStorage.get('bdAccessToken');
let header = new Headers({
'Authorization': 'Bearer '+ token
});
let ro = new RequestOptions({
headers: header
});
let options = new RequestOptions();
if (options.headers) options.headers.delete("Authorization");
options.headers = header;
return options;
}
Теперь я пытался разработать то же самое в Ionic, однако я не смог заставить его работать из-за асинхронного характера Ionic Storage. Получить значение из хранилища не так просто, как localStorage.get(item)
и вы должны сделать что-то вроде: storage.get(item).then(v => do stuff...)
,
Я ищу, чтобы создать AuthService и унаследованный класс Http, который работает как перехватчик; который выполняет следующую стандартную процедуру:
- Считывает токен доступа из хранилища, создает на его основе requestOptions и выполняет запрос.
- Если он выдает 401, он читает токен обновления из хранилища, получает новый токен доступа и сохраняет его в хранилище.
- Пытается выполнить исходный http-запрос с использованием нового токена доступа.
- Если по-прежнему не удается, перенаправляет пользователя на страницу входа.