我正在尝试存储从 Rest API 获取的授权令牌,然后在 Flutter 中其他 API 调用的标头中使用它 [英] I am trying to store the Authorization Token fetched from the Rest API and then use it in the headers of other API calls in Flutter

查看:17
本文介绍了我正在尝试存储从 Rest API 获取的授权令牌,然后在 Flutter 中其他 API 调用的标头中使用它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如问题的标题解释了大部分,但仍会详细说明.因此,我正在使用 POST 方法调用 API 并注册一个用户,该用户为我提供仅包含在调用其他 API 时需要使用的授权令牌的响应数据.

As the title of the problem explains most of it but will still elaborate more. So I am calling an API using the POST method and registering a user which gives me response data containing only the Authorization token which needs to be used while calling other APIs.

现在我想存储令牌并在进行其他 API 调用时在标头中使用它.我在此附上一些代码片段,它们可能会展示我实际做了什么以及为了获得特定结果需要做什么.我收到了用于获取密钥的 API 响应,但我无法理解为什么它没有被存储以及为什么我不能在标头中使用它.

Now I want to store the token and use it in the headers while making other API calls. I am herewith attaching a few code snippets that might demonstrate what I have done actually and what needs to be done in order to get the particular outcome. I am getting the API response for fetching the key but I am unable to understand why it is not getting stored and why cannot I use it in the headers.

API 调用只返回响应中的令牌

   final storage = SecureStorage();
Future<UserRegistration> registration(dynamic param) async {
    var client = http.Client();
    try {
      var response = await client
          .post(Uri.https("baseURL", "endpoint"),
              body: param)
          .timeout(Duration(seconds: TIME_CONST))
          .catchError(handleError);

      if (response.statusCode == 201) {
        print('Response Body: ${response.body}');
        final data = jsonDecode(response.body);

    ///////Using the flutter secure storage here to save the token

         var token = storage.writeSecureToken('key', data['key']);
          print("Token Here $token");
        return UserRegistration(
          key: data['key'],
          status: true,
        );
      } else {
        print("Something went wrong");
        return param;
      }
    } on SocketException {
      throw FetchDataException('message', 'url');
    } on TimeoutException {
      throw ApiNotRespondingException("message", "url");
    }
  }

我收到的 API 响应

Response Body: {"key":"8fb303212871a80899f0b883f3554b189fddf24b"}

我正在执行的 API 调用需要授权标头作为在上一个响应中收到的密钥.

Future<PhoneOTPValidate> phoneOTPvalidate(dynamic param) async {
    var client = http.Client();
    var token = storage.readSecureToken('key');
    try {
      var response = await client
          .post(
              Uri.https("baseURL", "endpoint"),
              headers: <String, String>{
                'Authorization': 'Token $token',
              },
              body: param)
          .timeout(Duration(seconds: TIME_CONST))
          .catchError(handleError);

      if (response.statusCode == 200) {
        print('Response Body: ${response.body}');
        final data = jsonDecode(response.body);
        return PhoneOTPValidate(
          status: data['success'],
          validate: true,
        );
      } else {
        print("The OTP is not valid");
        return param;
      }
    } on SocketException {
      throw FetchDataException('message', 'url');
    } on TimeoutException {
      throw ApiNotRespondingException("message", "url");
    }
  }

我的上述 API 调用类在这里:

class PhoneOTPValidate {
  PhoneOTPValidate({this.status, this.validate});
  final String? status;
  final bool? validate;
}

class UserRegistration {
  UserRegistration({this.key, this.status});
  final String? key;
  final bool? status;
}

Flutter 安全存储类

class SecureStorage {
  final storage = FlutterSecureStorage();
  Future writeSecureToken(String key, String value) async {
    var writeData = await storage.write(key: key, value: value);
    print('Token Here');
    return writeData;
  }

  Future readSecureToken(String key) async {
    var readData = await storage.read(key: key);
    return readData;
  }

  Future deleteSecureToken(String key) async {
    var deleteData = await storage.delete(key: key);
    return deleteData;
  }
}

这是我所写内容的输出:

Response Body: {"key":"de18d1239ed0b6be13f4c9a9d96eebeb1c401922"}
I/flutter (23010): Token Here Instance of 'Future<dynamic>'
I/flutter (23010): Token Here

如何解决保存密钥并在其他 API 调用的标头中使用它的问题?几乎尝试了 StackOverflow 中的所有解决方案,但没有任何人对它是如何完成的给出可靠的答案.我被这个问题困了好几天如果有人能考虑我的代码解决我的问题,我将不胜感激.

How do I solve this problem of saving the key and using it in the headers of the other API calls? Have almost tried all the solutions from StackOverflow but nothing gave a solid answer to how it is being done. Am stuck at this problem for quite a few days Would appreciate it if anyone can solve my problem considering my code.

推荐答案

问题是你没有等待"用于读取和写入安全令牌.这可以通过为变量提供显式类型来轻松避免.让我们修复您的代码:

The problem is that you don't "await" for secure token to be read and written. This can easily be avoided by providing explicit types for you variables. Let's fix your code:

//我假设您使用的是空安全

// I assume you are using null-safety

class SecureStorage {
  final FlutterSecureStorage storage = FlutterSecureStorage();
  Future<void> writeSecureToken(String key, String value) async {
    // I'm not exactly sure how you get the data from storage.write, because it has a type of Future<void>
    // So the whole function should be await storage.write(key: key, value: value);
    await storage.write(key: key, value: value);
  }

  Future<String?> readSecureToken(String key) async {
    return await storage.read(key: key);
  }

  Future<void> deleteSecureToken(String key) async {
    // Same here: delete is a type of void, so it shouldn't return anything
    await storage.delete(key: key);
  }
}

然后在更新安全存储完成后,我们可以开始获取令牌

Then with updating secured storage finished we can move to getting the token

final storage = SecureStorage();
Future<UserRegistration> registration(dynamic param) async {
  var client = http.Client();
  try {
    var response = await client
        .post(Uri.https("baseURL", "endpoint"), body: param)
        .timeout(Duration(seconds: TIME_CONST))
        .catchError(handleError);

    if (response.statusCode == 201) {
      print('Response Body: ${response.body}');
      final data = jsonDecode(response.body);

      ///////Using the flutter secure storage here to save the token
      String? token = data['key'];
      if (token == null) {
        throw Exception("No token in response");
      }
      
      await storage.writeSecureToken('key', token);
      print("Token Here $token");
      return UserRegistration(
        key: token,
        status: true,
      );
    } else {
      print("Something went wrong");
      return param;
    }
  } on SocketException {
    throw FetchDataException('message', 'url');
  } on TimeoutException {
    throw ApiNotRespondingException("message", "url");
  }
}

最后在您拨打电话时修复令牌的读取:

and finally fix the read for the token when you make a call:

Future<PhoneOTPValidate> phoneOTPvalidate(dynamic param) async {
  var client = http.Client();
  // Added type String? on the left side and await keyword for the storage.read()
  String? token = await storage.readSecureToken('key');
  if (token == null) {
    throw Exception("No token stored in storage");
  }
  try {
    var response = await client
        .post(
          Uri.https("baseURL", "endpoint"),
          headers: <String, String>{
            'Authorization': 'Token $token',
          },
          body: param,
        )
        .timeout(Duration(seconds: TIME_CONST))
        .catchError(handleError);

    if (response.statusCode == 200) {
      print('Response Body: ${response.body}');
      final data = jsonDecode(response.body);
      return PhoneOTPValidate(
        status: data['success'],
        validate: true,
      );
    } else {
      print("The OTP is not valid");
      return param;
    }
  } on SocketException {
    throw FetchDataException('message', 'url');
  } on TimeoutException {
    throw ApiNotRespondingException("message", "url");
  }
}

这篇关于我正在尝试存储从 Rest API 获取的授权令牌,然后在 Flutter 中其他 API 调用的标头中使用它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆