如何在我的 Flutter 应用程序中从 JWT 获取声明

Posted

技术标签:

【中文标题】如何在我的 Flutter 应用程序中从 JWT 获取声明【英文标题】:How to get the claims from a JWT in my Flutter Application 【发布时间】:2019-01-31 16:44:52 【问题描述】:

我正在编写一个 Flutter/Dart 应用程序,并且正在从一个身份验证服务器返回一个 JWT,该服务器有一些我需要使用的声明。我已经查看了各种(到目前为止 4 个)Dart JWT 库——但要么都太旧,不再与 Dart 2 一起工作,等等。或者他们需要秘密来解码 JWT,这没有意义而且不正确(或可能,因为我无权访问)。

那么——如何在“现代”Dart/Flutter 应用程序中获取 JWT 并从中获取声明?

【问题讨论】:

【参考方案1】:

JWT 令牌只是 base64 编码的 JSON 字符串(其中 3 个,用点分隔):

import 'dart:convert';

Map<String, dynamic> parseJwt(String token) 
  final parts = token.split('.');
  if (parts.length != 3) 
    throw Exception('invalid token');
  

  final payload = _decodeBase64(parts[1]);
  final payloadMap = json.decode(payload);
  if (payloadMap is! Map<String, dynamic>) 
    throw Exception('invalid payload');
  

  return payloadMap;


String _decodeBase64(String str) 
  String output = str.replaceAll('-', '+').replaceAll('_', '/');

  switch (output.length % 4) 
    case 0:
      break;
    case 2:
      output += '==';
      break;
    case 3:
      output += '=';
      break;
    default:
      throw Exception('Illegal base64url string!"');
  

  return utf8.decode(base64Url.decode(output));

【讨论】:

这是完美的。让我困惑的是填充物——这是一个非常好的例程——谢谢!现在,我不知道为什么这个小程序不在一个不错的 JWT 包中! :) (或者如果它不容易看到!) 我想我只是从 Dart 1 JWT 包之一中获取它,添加了一些类型,小写常量...... 谢谢它对我有用。我打印 utf8.decode(base64url.decode(output)).. 结果是字符串。如何只获取一个键值? 当您运行parseJwt() 时,您会得到Map 结果。使用map['key'] 获取键的值。 我有一个关于 JWT 与 Flutter 应用程序一起使用的问题,如果我们的移动应用程序中有大量用户(1 到 20 万用户)有什么问题或者最大用户数是多少,那在 JWT 实现中是允许的。【参考方案2】:

使用“base64Url.normalize()”函数。 这就是 _decodeBase64() 从上面的答案中所做的!

String getJsonFromJWT(String splittedToken)
  String normalizedSource = base64Url.normalize(encodedStr);
  return utf8.decode(base64Url.decode(normalizedSource));

【讨论】:

【参考方案3】:

在撰写本文时,jaguar_jwt 包正在积极维护中。尽管没有明确记录,但它确实有一个可以解码 Base64Url 编码的公共方法。它与接受的答案基本相同。

//import 'package:jaguar_jwt/jaguar_jwt.dart';

final String token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NTQ4MjAxNjIsImlhdCI6MTU1NDc3Njk2MiwiaXNzIjoiU3VyYWdjaCIsInN1YiI6IjQifQ.bg5B_k9WCmxiu2epuZo_Tpt_KZC4N9ve_2GEdrulcXM';
final parts = token.split('.');
final payload = parts[1];
final String decoded = B64urlEncRfc7515.decodeUtf8(payload);

这给出了一个 JSON 字符串,对于这个特定的示例,它是:


  "exp":1554820162,
  "iat":1554776962,
  "iss":"Suragch",
  "sub":"4"

另见:

JWT: The Complete Guide to JSON Web Tokens String based data encoding: Base64 vs Base64url

【讨论】:

【参考方案4】:

您可以通过单独包含“.”的第一部分来解码 JWT base64

      String decodeUserData(String code) 
      String normalizedSource = base64Url.normalize(code.split(".")[1]);
      return utf8.decode(base64Url.decode(normalizedSource));
      

【讨论】:

以上是关于如何在我的 Flutter 应用程序中从 JWT 获取声明的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的视图中从请求对象获取 jwt 有效负载

如何在flutter中从其他android型号中检测华为设备型号?

如何在 Flutter 中从 Web 加载和呈现 PDF 文件

如何在flutter中从firebase实时数据库中获取数据?

如何在我的颤振应用程序中从 bing web search apiv7 获取图像

在 Flutter 中从 Notification Service Extension 更改 CFBundleVersion #66448