android “授权”:'Bearer $token' -发送的令牌为NULL的原因

jjhzyzn0  于 2023-09-28  发布在  Android
关注(0)|答案(3)|浏览(224)

我尝试在Android上用Flutter构建一个应用程序。readData()方法发送了'Authorization': 'Bearer $token' HTTP标头。问题是$token未正确发送,服务器上接收到Null。我尝试发送$token${token},纯文本令牌(字符串)-没有工作。
当我尝试从https://reqbin.com/post-online发送包含token作为纯文本的get请求时,它工作得很好。
你能告诉我是什么原因导致了这个问题吗?

Future readData() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String token = prefs.getString('token').toString();

    print('Token : $token');     // prints $token OK

    final response = await get(
        Uri.parse('https://www.somehost.com/api.php'),
        headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Authorization': 'Bearer $token',     // here token is null (read from server log)
        }
      );

    print(response.statusCode);

    var data = jsonDecode(response.body.toString());
    print(data);
    print(data['success']);
    print(data['user']['email']);
  }

API代码:

<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: access");
header("Access-Control-Allow-Methods: GET");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

require __DIR__.'/classes/db.php';
require __DIR__.'/auth.php';

$allHeaders = getallheaders();
$db_connection = new Database();
$conn = $db_connection->dbConnection();
$auth = new Auth($conn, $allHeaders);

echo json_encode($auth->isValid());
?>
ru9i0ody

ru9i0ody1#

您所面临的问题,即令牌没有被正确发送,并且在服务器上被接收为null,可能与您如何从Flutter中的SharedPreferences中检索令牌有关。
从SharedPreferences检索令牌的代码看起来很好:

String token = prefs.getString('token').toString();

但是,如果SharedPreferences中没有存储令牌,或者没有正确检索存储的令牌,则可能会出现问题。
以下是解决此问题的一些步骤:
在SharedPreferences中检查令牌:首先,请确保您已在应用的早期某个位置将令牌正确保存在SharedPreferences中。验证令牌是否使用键'token'保存,并且此时它不为null。
打印令牌值:在发出HTTP请求之前,将token的值打印到控制台,以验证它是否从SharedPreferences中正确检索。

print('Token : $token');

如果这个print语句正确地显示了令牌,这意味着它正按预期从SharedPreferences中检索。
HTTP请求标头:您在Authorization标头中使用令牌的方式看起来是正确的:

'Authorization': 'Bearer $token'

确保此时令牌不为空或null。你可以打印出来验证。
检查请求中的令牌:您可以在服务器端添加一些调试代码来检查服务器接收到的实际头。记录标头以查看Authorization标头是否包含令牌。举例来说:

$token = isset($allHeaders['Authorization']) ? $allHeaders['Authorization'] : 'No token provided';
error_log('Received Token: ' . $token);

这将帮助您确定令牌是否确实从客户端发送到服务器。
API终点:仔细检查API端点'https://www.somehost.com/api.php'是否是正确的端点,并且它需要您提供的格式的Authorization标头。
CORS问题:确保没有CORS(跨域资源共享)问题阻止请求被正确处理。您在服务器端设置的头应该允许来自任何来源的请求(“Access-Control-Allow-Origin:* ”).
通过仔细检查这些点并在各个阶段(从存储到检索再到请求)验证令牌,您应该能够识别并解决导致令牌在服务器端为空的问题。

ix0qys7i

ix0qys7i2#

使用

String token = await prefs.getString('token');

而不是

String token = prefs.getString('token').toString();

因为prefs.getString()返回一个Future,所以需要添加await。

ahy6op9u

ahy6op9u3#

您需要添加await,就好像您没有添加您编写的print命令一样,API调用将一起触发,因此这就是为什么您看到令牌也被打印了正确的值,但API已经被调用。使用await确保您首先接收令牌,然后只调用API。所以我同意MSC的观点,你需要这样做才能起作用

String token = await prefs.getString('token');

相关问题