私は間違っているかどうかわからないので、これが可能かどうかを知りたいです。基本的には、ネイティブfetch
javascript関数のラップ関数を作成することです。このラップ関数はトークンの検証プロセスを実装し、指定されたトークンが期限切れになった場合に新しいaccessToken
を要求し、再度要求するリソースを要求します。これは私が今までに達してきたものである:カスタム機能を追加するためにjavascriptをフェッチする
customFetch.js
// 'url' and 'options' parameters are used strictely as you would use them in fetch. 'authOptions' are used to configure the call to refresh the access token
window.customFetch = (url, options, authOptions) => {
const OPTIONS = {
url: '',
unauthorizedRedirect: '',
storage: window.sessionStorage,
tokenName: 'accessToken'
}
// Merge options passed by user with the default auth options
let opts = Object.assign({}, OPTIONS, authOptions);
// Try to update 'authorizarion's header in order to send always the proper one to the server
options.headers = options.headers || {};
options.headers['Authorization'] = `Bearer ${opts.storage.getItem(opts.tokenName)}`;
// Actual server request that user wants to do.
const request = window.fetch(url, options)
.then((d) => {
if (d.status === 401) {
// Unauthorized
console.log('not authorized');
return refreshAccesToken();
}
else {
return d.json();
}
});
// Auxiliar server call to get refresh the access token if it is expired. Here also check if the
// cookie has expired and if it has expired, then we should redirect to other page to login again in
// the application.
const refreshAccesToken =() => {
window.fetch(opts.url, {
method: 'get',
credentials: 'include'
}).then((d) => {
// For this example, we can omit this, we can suppose we always receive the access token
if (d.status === 401) {
// Unauthorized and the cookie used to validate and refresh the access token has expired. So we want to login in to the app again
window.location.href = opts.unauthorizedRedirect;
}
return d.json();
}).then((json) => {
const jwt = json.token;
if (jwt) {
// Store in the browser's storage (sessionStorage by default) the refreshed token, in order to use it on every request
opts.storage.setItem(opts.tokenName, jwt);
console.log('new acces token: ' + jwt);
// Re-send the original request when we have received the refreshed access token.
return window.customFetch(url, options, authOptions);
}
else {
console.log('no token has been sent');
return null;
}
});
}
return request;
}
consumer.js
const getResourcePrivate =() => {
const url = MAIN_URL + '/resource';
customFetch(url, {
method: 'get'
},{
url: AUTH_SERVER_TOKEN,
unauthorizedRedirect: AUTH_URI,
tokenName: TOKEN_NAME
}).then((json) => {
const resource = json ? json.resource : null;
if (resource) {
console.log(resource);
}
else {
console.log('No resource has been provided.');
}
});
}
私は少し良く、上記のコードを説明してみましょう:私は、ユーザーのために透明にします彼らが望むリソースを要求することを心配するために、トークンの検証を行います。 return request
命令は、fetch
要求の約束を消費者に与えているので、このアプローチはaccessToken
が依然として有効であるときにうまく動作しています。
もちろん、accessToken
が期限切れになり、新しいサーバをauth
サーバにリクエストすると、これは動作しません。トークンがリフレッシュされ、プライベートリソースが要求されますが、consumer.js
にはトークンが表示されません。
この最後のシナリオでは、accessToken
をリフレッシュしてプライベートリソースを再度取得するためにサーバーコールを実行するために、プログラムのフローを変更できますか?消費者はこのプロセスについて理解すべきではありません。両方とも(accessToken
が有効で、accessToken
が期限切れになり、更新されている)、consumer.js
は、then
機能でプライベートに要求されたリソースを取得する必要があります。
ああ、私は遅すぎると思う:DIはここで一組の括弧を取り除くことを提案したいと思った。const refreshAccesToken =()=> window.fetch(...); 'このように' refreshAccesToken'はaを返すべきです約束されていません。すべてが正常に動作しているはずです。 –
@Dennisあなたは正しいです!Yはその機能に間違いを犯し、私は約束を返すのを忘れた。私は試してみましたが、うまくいきましたので、私の答えを編集してあなたのアプローチを追加しました。 – christiansr85