我目前正在Flutter中尝试访问一个需要JWT访问令牌授权的Web API,访问令牌会在一段时间后过期。
可以使用单独的刷新令牌请求新的访问令牌。现在,只要请求返回401响应,就会执行此访问令牌刷新。之后,应使用新的访问令牌重试失败的请求。
我在最后一步遇到了麻烦。看起来http.BaseRequest
只能发送一次。我如何使用新令牌重试http请求?
正如dart http自述文件中所建议的,我创建了http.BaseClient
的一个子类来添加授权行为,下面是一个简化版本:
import 'dart:async';
import 'package:http/http.dart' as http;
class AuthorizedClient extends http.BaseClient {
AuthorizedClient(this._authService) : _inner = http.Client();
final http.Client _inner;
final AuthService _authService;
Future<http.StreamedResponse> send(http.BaseRequest request) async {
final token = await _authService.getAccessToken();
request.headers['Authorization'] = 'Bearer $token';
final response = await _inner.send(request);
if (response.statusCode == 401) {
final newToken = await _authService.refreshAccessToken();
request.headers['Authorization'] = 'Bearer $newToken';
// throws error: Bad state: Can't finalize a finalized Request
final retryResponse = await _inner.send(request);
return retryResponse;
}
return response;
}
}
abstract class AuthService {
Future<String> getAccessToken();
Future<String> refreshAccessToken();
}
3条答案
按热度按时间mspsb9vt1#
以下是我根据理查德·希普的回答得出的结论:要重新发送请求,我们必须复制它。
到目前为止,我还无法提出流请求的解决方案!
2q5ifsrm2#
不能对同一个
BaseRequest
执行两次send
。请根据第一个BaseRequest
创建一个新的BaseRequest
,然后发送该副本。下面是一些代码(来自io_client),用于“克隆”BaseRequest。
67up9zun3#
似乎发送相同的表单数据而不完成最后一个请求的问题,通过以下方式解决了相同的问题:
在401块中这样使用它: