Flutter JWT解码插件jsonwebtoken_decode的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter JWT解码插件 jsonwebtoken_decode 的使用

jsonwebtoken_decode 是一个用于解码 JSON Web Token (JWT) 并选择特定声明的 Flutter 插件。它支持获取 Header 和 Payload 声明、OpenID 声明、Keycloak 声明以及自定义声明。

特性

  • 解码 JWT;
  • 获取 Header 和 Payload 声明;
  • 获取 OpenID 声明;
  • 获取 Keycloak 声明;
  • 获取自定义声明。

使用示例

基本用法

以下是如何使用 jsonwebtoken_decode 包的基本示例:

import 'package:flutter/material.dart';
import 'package:jsonwebtoken_decode/jsonwebtoken_decode.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'JWT Decode and Claims Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'JWT Decode and Claims Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final String _token =
      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";
  late JwtBuilder _jwtBuilder;
  late HeaderClaims _headerClaims;
  late PayloadClaims _payloadClaims;
  late OpenIdClaims _openIdClaims;

  final _headerTextStyle = const TextStyle(color: Colors.red);
  final _payloadTextStyle = const TextStyle(color: Colors.purple);
  final _verifySignatureTextStyle = const TextStyle(color: Colors.cyan);

  @override
  void initState() {
    super.initState();

    _jwtBuilder = JwtBuilder.fromToken(_token);
    _payloadClaims = PayloadClaims(_jwtBuilder);
    _headerClaims = HeaderClaims(_jwtBuilder);
    _openIdClaims = OpenIdClaims(_jwtBuilder);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: <Widget>[
              _buildTokenExampleText(),
              const SizedBox(height: 32),
              _buildDecodedToken(),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildTokenExampleText() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        const Text(
          'JWT example: https://jwt.io/',
          style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
        ),
        const SizedBox(height: 24),
        const Text('Full token:'),
        const SizedBox(height: 8),
        const Text(
            'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'),
        const SizedBox(height: 24),
        const Text('Header'),
        Text(
          'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9',
          style: _headerTextStyle,
        ),
        const SizedBox(height: 24),
        const Text('Payload'),
        Text(
          'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ',
          style: _payloadTextStyle,
        ),
        const SizedBox(height: 24),
        const Text('Verify Signature'),
        Text(
          'SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
          style: _verifySignatureTextStyle,
        ),
      ],
    );
  }

  Widget _buildDecodedToken() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        const Text('Decoded Header Claims:'),
        const SizedBox(height: 8),
        Text(
          '{',
          style: _headerTextStyle,
        ),
        Text(
          '    "alg" : "${_headerClaims.alg}"',
          style: _headerTextStyle,
        ),
        Text(
          '    "typ" : "${_headerClaims.typ}"',
          style: _headerTextStyle,
        ),
        Text(
          '}',
          style: _headerTextStyle,
        ),
        const SizedBox(height: 24),
        const Text('Decoded Payload Claims:'),
        Text(
          '{',
          style: _payloadTextStyle,
        ),
        Text(
          '    "sub" : "${_payloadClaims.sub}"',
          style: _payloadTextStyle,
        ),
        Text(
          '    "name" : "${_openIdClaims.name}"',
          style: _payloadTextStyle,
        ),
        Text(
          '    "iat" : "${_payloadClaims.iat}"',
          style: _payloadTextStyle,
        ),
        Text(
          '}',
          style: _payloadTextStyle,
        ),
      ],
    );
  }
}

使用声明

你可以通过以下方式获取各种类型的声明:

final String _token ='valid_token';
JwtBuilder? _jwtBuilder;
PayloadClaims? _payloadClaims;
OpenIdClaims? _openIdClaims;
KeycloakClaims? _keycloakClaims;
HeaderClaims? _headerClaims;

@override
void initState() {
    super.initState();
    _jwtBuilder = JwtBuilder.fromToken(_token);
    _payloadClaims = PayloadClaims(_jwtBuilder!);
    _openIdClaims = OpenIdClaims(_jwtBuilder!);
    _keycloakClaims = KeycloakClaims(_jwtBuilder!);
    _headerClaims = HeaderClaims(_jwtBuilder!);
}

// ...

Text('${_payloadClaims!.sub}'),
Text('${_openIdClaims!.name}'),
Text('${_keycloakClaims!.rolesRealmAccess}'),
Text('${_headerClaims!.typ}'),

创建自定义的 PayloadClaims 类

如果你有自定义的声明,可以通过扩展 PayloadClaims 类来实现:

class MyClaims extends PayloadClaims {
  MyClaims(super.jwtBuilder);

  get myPublicClaim => claim('my_public_claim');
}

更多关于Flutter JWT解码插件jsonwebtoken_decode的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter JWT解码插件jsonwebtoken_decode的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,我可以为你提供一个关于如何在Flutter中使用jsonwebtoken_decode插件来解码JWT(JSON Web Token)的示例代码。

首先,确保你已经在pubspec.yaml文件中添加了jsonwebtoken_decode依赖:

dependencies:
  flutter:
    sdk: flutter
  jsonwebtoken_decode: ^x.y.z  # 请将x.y.z替换为最新版本号

然后,运行flutter pub get来安装依赖。

以下是一个简单的Flutter应用示例,演示如何使用jsonwebtoken_decode插件来解码JWT:

import 'package:flutter/material.dart';
import 'package:jsonwebtoken_decode/jsonwebtoken_decode.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter JWT Decode Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String? decodedToken;
  String? errorMessage;

  void decodeJWT(String token) async {
    try {
      var decoded = await JwtDecoder.decode(token);
      setState(() {
        decodedToken = decoded.toString();
        errorMessage = null;
      });
    } catch (e) {
      setState(() {
        decodedToken = null;
        errorMessage = e.toString();
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter JWT Decode Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            TextField(
              decoration: InputDecoration(
                labelText: 'Enter JWT Token',
              ),
              maxLines: 10,
              expands: true,
              onEditingComplete: () {
                // Assuming the token is in the form of a single line for simplicity
                String? token = textController.text.trim();
                if (token != null && token.isNotEmpty) {
                  decodeJWT(token);
                }
              },
              controller: _buildTextController(),
            ),
            SizedBox(height: 16),
            if (errorMessage != null)
              Text(
                'Error: $errorMessage',
                style: TextStyle(color: Colors.red),
              ),
            if (decodedToken != null)
              Text(
                'Decoded Token: $decodedToken',
                style: TextStyle(color: Colors.green),
              ),
          ],
        ),
      ),
    );
  }

  TextEditingController _buildTextController() {
    return TextEditingController();
  }
}

注意事项

  1. 在实际使用中,你可能需要更复杂的逻辑来处理JWT的输入和错误处理。
  2. 上面的示例代码假设JWT token是一个单行字符串,并通过TextFieldonEditingComplete回调来触发解码。
  3. JwtDecoder.decode(token)方法会返回一个包含JWT载荷(payload)的Map对象。

注意:由于jsonwebtoken_decode插件的具体实现和API可能会随着版本变化,请参考插件的官方文档和示例代码以确保兼容性。如果插件的API有所变动,你可能需要调整上述代码。

回到顶部