Flutter 如何将 Auth 令牌从 Flutter 安全存储设置为 dio header?
Flutter how can i set Auth token from flutter secure storage to dio header?
登录后,我将用户令牌设置为我的用户安全存储。喜欢:
Future<AuthResponseModel?> login(AuthRequstModel model) async {
try {
Response response = await _dio.post(loginPath, data: model);
if (response.statusCode == 200) {
final AuthResponseModel authResponseModel = AuthResponseModel.fromJson(response.data);
if (authResponseModel.success!) {
await UserSecureStorage.setField("token", authResponseModel.token);
}
return AuthResponseModel.fromJson(response.data);
}
return null;
} catch (e) {
return null;
}
}
用户安全存储 =>
class UserSecureStorage {
static const _storage = FlutterSecureStorage();
static Future setField(String key, value) async {
await _storage.write(key: key, value: value);
}
static Future<String?> getField(key) async {
return await _storage.read(key: key);
}
但问题是,当我想制作 apiservice 时,当我想在 dio 的 header 中验证令牌时,我无法访问它,因为它是 future 函数。但我不能使用 await 因为它在 baseoption 内部。喜欢:
class ApiService {
final _dio = Dio(BaseOptions(headers: {
'authorization': 'Bearer ${UserSecureStorage.getField("token")}', //I cant access here its only giving instance.
}));
Future<Response?> get(String path) async {
try {
Response response = await _dio.get('${ApiConstants.BASE_URL}$path');
if (response.statusCode == 200) {
return response;
}
return null;
} on DioError catch (e) {
return null;
}
}
我能做些什么来解决这个问题?我在尝试获取令牌后尝试使用 .then(value=>value) 但也没有用。感谢回复!
你正在获取实例,因为 UserSecureStorage.getField("token") 是未来的,所以当你输入 await 关键字时你可以获得令牌
所以这样试试
等待UserSecureStorage.getField("令牌")
我认为令牌没有得到更新,因为 _dio
已经初始化。
尝试在发出 dio 请求时请求令牌,例如:
class ApiService {
final _dio = Dio();
Future<Response?> get(String path) async {
try {
Response response = await _dio.get('${ApiConstants.BASE_URL}$path', options: Options(headers: {"authorization": "Bearer ${UserSecureStorage.getField("token")}"}));
if (response.statusCode == 200) {
return response;
}
return null;
} on DioError catch (e) {
return null;
}
}
对所有请求在 get method to add headers
for a single request or interceptors 中使用 options
。
我认为这不是一个容易解决的问题,我会尝试两种不同的方法,您可以在 Provider 等状态管理器中维护令牌,这样您就不必依赖异步函数来检索它,但这当然会在代码中添加状态管理器结构,这会使事情变得有点复杂。
解决这个问题的更简单的方法是在 ApiService 中包含一个异步初始化器 class 这样
class ApiService {
late final _dio;
Future<void> init() async {
_dio = Dio(BaseOptions(headers: {
'authorization': 'Bearer ${UserSecureStorage.getField("token")}', //I cant access here its only giving instance.
}));}
Future<Response?> get(String path) async {
try {
Response response = await _dio.get('${ApiConstants.BASE_URL}$path');
if (response.statusCode == 200) {
return response;
}
return null;
} on DioError catch (e) {
return null;
}
}
这给我们带来了一个新问题,我们必须在每次实例化 class ApiService 时调用 init,要解决这个问题,您可以使用包 get_it,它只允许实例化一旦 class 并从项目中的任何地方访问它。
希望本文能帮助您解决问题
登录后,我将用户令牌设置为我的用户安全存储。喜欢:
Future<AuthResponseModel?> login(AuthRequstModel model) async {
try {
Response response = await _dio.post(loginPath, data: model);
if (response.statusCode == 200) {
final AuthResponseModel authResponseModel = AuthResponseModel.fromJson(response.data);
if (authResponseModel.success!) {
await UserSecureStorage.setField("token", authResponseModel.token);
}
return AuthResponseModel.fromJson(response.data);
}
return null;
} catch (e) {
return null;
}
}
用户安全存储 =>
class UserSecureStorage {
static const _storage = FlutterSecureStorage();
static Future setField(String key, value) async {
await _storage.write(key: key, value: value);
}
static Future<String?> getField(key) async {
return await _storage.read(key: key);
}
但问题是,当我想制作 apiservice 时,当我想在 dio 的 header 中验证令牌时,我无法访问它,因为它是 future
class ApiService {
final _dio = Dio(BaseOptions(headers: {
'authorization': 'Bearer ${UserSecureStorage.getField("token")}', //I cant access here its only giving instance.
}));
Future<Response?> get(String path) async {
try {
Response response = await _dio.get('${ApiConstants.BASE_URL}$path');
if (response.statusCode == 200) {
return response;
}
return null;
} on DioError catch (e) {
return null;
}
}
我能做些什么来解决这个问题?我在尝试获取令牌后尝试使用 .then(value=>value) 但也没有用。感谢回复!
你正在获取实例,因为 UserSecureStorage.getField("token") 是未来的,所以当你输入 await 关键字时你可以获得令牌
所以这样试试
等待UserSecureStorage.getField("令牌")
我认为令牌没有得到更新,因为 _dio
已经初始化。
尝试在发出 dio 请求时请求令牌,例如:
class ApiService {
final _dio = Dio();
Future<Response?> get(String path) async {
try {
Response response = await _dio.get('${ApiConstants.BASE_URL}$path', options: Options(headers: {"authorization": "Bearer ${UserSecureStorage.getField("token")}"}));
if (response.statusCode == 200) {
return response;
}
return null;
} on DioError catch (e) {
return null;
}
}
对所有请求在 get method to add headers
for a single request or interceptors 中使用 options
。
我认为这不是一个容易解决的问题,我会尝试两种不同的方法,您可以在 Provider 等状态管理器中维护令牌,这样您就不必依赖异步函数来检索它,但这当然会在代码中添加状态管理器结构,这会使事情变得有点复杂。
解决这个问题的更简单的方法是在 ApiService 中包含一个异步初始化器 class 这样
class ApiService {
late final _dio;
Future<void> init() async {
_dio = Dio(BaseOptions(headers: {
'authorization': 'Bearer ${UserSecureStorage.getField("token")}', //I cant access here its only giving instance.
}));}
Future<Response?> get(String path) async {
try {
Response response = await _dio.get('${ApiConstants.BASE_URL}$path');
if (response.statusCode == 200) {
return response;
}
return null;
} on DioError catch (e) {
return null;
}
}
这给我们带来了一个新问题,我们必须在每次实例化 class ApiService 时调用 init,要解决这个问题,您可以使用包 get_it,它只允许实例化一旦 class 并从项目中的任何地方访问它。
希望本文能帮助您解决问题