Flutter如何实现JWT认证

在Flutter中如何实现JWT认证?想在后端使用Node.js生成JWT令牌,但不太清楚Flutter端的具体实现步骤。目前主要遇到以下几个问题:

  1. 如何在Flutter中安全存储JWT令牌?
  2. 发送请求时应该如何携带JWT令牌?
  3. 如何正确处理JWT过期和刷新令牌的逻辑? 有没有完整的代码示例可以参考?或者推荐一些好用的Flutter JWT认证插件?
2 回复

Flutter中实现JWT认证通常使用dart:convert解码token,结合shared_preferences存储token。发送请求时在header添加Authorization: Bearer <token>。推荐使用httpdio库处理网络请求,并验证token有效期。

更多关于Flutter如何实现JWT认证的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现JWT认证,主要通过以下步骤:

1. 接收和存储JWT

import 'package:shared_preferences/shared_preferences.dart';

// 存储Token
Future<void> saveToken(String token) async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString('jwt_token', token);
}

// 读取Token
Future<String?> getToken() async {
  final prefs = await SharedPreferences.getInstance();
  return prefs.getString('jwt_token');
}

// 删除Token(退出登录)
Future<void> removeToken() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.remove('jwt_token');
}

2. 网络请求携带JWT 使用httpdio包发送请求时,在header中添加Token:

import 'package:dio/dio.dart';

Future<void> fetchUserData() async {
  String? token = await getToken();
  
  Dio dio = Dio();
  dio.options.headers = {
    'Authorization': 'Bearer $token',
    'Content-Type': 'application/json'
  };
  
  try {
    Response response = await dio.get('https://api.example.com/user');
    print(response.data);
  } catch (e) {
    print('请求失败: $e');
  }
}

3. Token自动刷新(可选)

// 检查Token是否即将过期
bool isTokenExpired(String token) {
  // 解析JWT payload(实际项目建议使用jwt_decode包)
  final parts = token.split('.');
  if (parts.length != 3) return true;
  
  final payload = _decodeBase64(parts[1]);
  final payloadMap = json.decode(payload);
  final exp = payloadMap['exp'] as int;
  final currentTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;
  
  return exp - currentTime < 300; // 5分钟内过期
}

// 刷新Token
Future<String?> refreshToken() async {
  // 实现刷新逻辑,通常调用特定API
}

4. 完整认证流程示例

class AuthService {
  Future<bool> login(String email, String password) async {
    try {
      Response response = await Dio().post(
        'https://api.example.com/login',
        data: {'email': email, 'password': password},
      );
      
      if (response.statusCode == 200) {
        await saveToken(response.data['token']);
        return true;
      }
    } catch (e) {
      print('登录失败: $e');
    }
    return false;
  }

  Future<void> logout() async {
    await removeToken();
    // 跳转到登录页面
  }
}

关键点:

  • 使用shared_preferences安全存储Token
  • 每个请求在Header中添加Authorization: Bearer <token>
  • 处理Token过期和自动刷新
  • 考虑使用拦截器自动管理Token(Dio支持)

建议使用dio包配合拦截器实现更完善的认证流程,可以自动处理Token刷新和重试逻辑。

回到顶部