You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter端如何正确解析JWT中来自MySQL的Binary UUID?

问题背景

我在MySQL创建了如下表结构:

CREATE TABLE IF NOT EXISTS auth (
  id BINARY(16) PRIMARY KEY);

在Node.js应用中生成了二进制UUID:

user_id = id: <Buffer 11 ed cd 15 15 37 82 00 bf fe a5 5d 53 c7 95 d9>

随后将用户插入表并签名JWT:

const jwt = jwt.sign(
  {user_id : user_id},
  process.env.JWT_KEY!,
  {
    expiresIn: process.env.JWT_EXPIRES_IN,
  }
);

但在Flutter前端提取token中的user_id时,使用以下代码:

final responseData = json.decode(response.body);
if (responseData['error'] != null) {
  throw HttpException(responseData['error']['message']);
}
_token = responseData['token'];
Map<String, dynamic> decodedToken = JwtDecoder.decode(_token!);

打印decodedToken得到:

{type: Buffer, data: [17, 237, 205, 21, 21, 55, 130, 0, 191, 254, 165, 93, 83, 199, 149, 217]}

原因分析

  • Node.js中的Buffer对象在被jsonwebtoken库序列化到JWT Payload时,会被自动转换成包含type和data的JSON结构——这是JSON规范中对二进制数据的标准序列化方式,因为JSON本身不支持原生二进制类型。
  • JWT的Payload本质是JSON格式,无法直接存储二进制数据,所以Buffer会被转成这种结构化对象,导致前端解码后得到的不是原始UUID值,而是Buffer的序列化结果。

解决方案

方案一:服务端(Node.js)提前转成字符串存入JWT

推荐在签名JWT前,把二进制UUID转换成十六进制字符串或者标准UUID格式字符串,这样前端解码后直接拿到可用的字符串:

// 转成十六进制字符串
const userIdStr = user_id.toString('hex');

// 如果你是用uuid库生成的二进制UUID,也可以直接转成标准UUID格式
// const userIdStr = require('uuid').stringify(user_id);

const jwt = jwt.sign(
  {user_id: userIdStr},
  process.env.JWT_KEY!,
  {
    expiresIn: process.env.JWT_EXPIRES_IN,
  }
);

前端解码后decodedToken['user_id']就是普通字符串,若需要在Flutter端转回二进制,可将十六进制字符串转成Uint8List。

方案二:前端(Flutter)将Buffer结构转回二进制UUID

如果服务端无法修改,前端可以把解码后的data数组转成二进制数据,再按需转成字符串:

// 提取Buffer的data数组并转成Uint8List
List<int> bufferData = decodedToken['user_id']['data'].cast<int>();
Uint8List userIdBytes = Uint8List.fromList(bufferData);

// 转成十六进制字符串
String userIdHex = userIdBytes
    .map((byte) => byte.toRadixString(16).padLeft(2, '0'))
    .join('');

// 若需要标准UUID格式,可添加格式化函数
String _formatToUuid(Uint8List bytes) {
  assert(bytes.length == 16);
  String hex = userIdBytes
      .map((b) => b.toRadixString(16).padLeft(2, '0'))
      .join('');
  return '${hex.substring(0,8)}-${hex.substring(8,12)}-${hex.substring(12,16)}-${hex.substring(16,20)}-${hex.substring(20)}';
}
// 使用:String userIdUuid = _formatToUuid(userIdBytes);

内容的提问来源于stack exchange,提问作者best_of_man

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 22:53:10