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
相关产品推荐
相关产品推荐

