Flutter APP 接口安全处理
2020-11-27 本文已影响0人
梁典典
先放上工具类,记录一下
import 'dart:convert';
import 'package:crypto/crypto.dart';
import 'package:encrypt/encrypt.dart';
class Utils {
static const String IP = "http://192.168.199.118:8089";
static const String _KEY = "76CAA1C88F7F8D1D";
static const String _IV = "91129048100F0494";
/// 根据request参数的key进行排序,并生成一个新的map返回
static Map<String, String> keySort(Map<String, String> oldParamsMap) {
Map<String, String> newParamsMap = Map();
String timeToken = DateTime.now().millisecondsSinceEpoch.toString();
oldParamsMap["time_token"] = timeToken; // 给参数加上时间戳
List<String> oldKeys = oldParamsMap.keys.toList();
if (oldKeys.isEmpty) return newParamsMap;
oldKeys.sort((a, b) {
List<int> al = a.codeUnits;
List<int> bl = b.codeUnits;
for (int i = 0; i < al.length; i++) {
if (bl.length <= i) return 1;
if (al[i] > bl[i]) {
return 1;
} else if (al[i] < bl[i]) return -1;
}
return 0;
});
// print(oldKeys);
for (int i = 0; i < oldKeys.length; i++) {
newParamsMap[oldKeys[i]] = oldParamsMap[oldKeys[i]];
}
return newParamsMap;
}
/// 生成token
static String generateToken(Map<String, String> params) {
String value = json.encode(params);
// utf8编码
// print("编码前的串串:$value");
value = base64Encode(utf8.encode(value));
// print("编码后的串串:$value");
value = encryptMD5(value);
return value;
}
/// aes 加密
static String encryptAESCbc128WithPadding7(String val) {
String v = "";
try {
final encrypter = Encrypter(AES(Key.fromUtf8(_KEY), mode: AESMode.cbc));
final encrypted = encrypter.encrypt(val, iv: IV.fromUtf8(_IV));
return encrypted.base64;
} catch (err) {
print("加密失败:$err");
}
return v;
}
/// md5 加密
static String encryptMD5(String data) {
var content = new Utf8Encoder().convert(data);
var digest = md5.convert(content);
return digest.toString();
}
}
要用到的插件
device_info: ^1.0.0
dio: ^3.0.10
crypto: ^2.1.5
encrypt: ^4.1.0
测试页面
import 'dart:convert';
import 'package:device_info/device_info.dart';
import 'package:dio/dio.dart';
import 'package:encrypt/util.dart';
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String _deviceId = ""; // 设备id
String _response = ""; // 服务器返回的数据
@override
void initState() {
super.initState();
_getDeviceId();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("加密请求测试"),
),
body: SingleChildScrollView(
child: Column(
children: [
Text("设备id是:$_deviceId"),
MaterialButton(child: Text("获取设备id"), onPressed: _getDeviceId),
MaterialButton(
onPressed: _getAccessToken,
child: Text("获取服务器token"),
),
MaterialButton(
onPressed: _paramsSort,
child: Text("参数排序"),
),
Column(
children: [
Divider(),
Text(_response)
],
)
],
),
),
);
}
Future<void> _paramsSort()async{
Map<String,String> params = Map();
params["pageId"] = "1";
params["pageSize"] = "10";
params["sort"] = "1";
params["goodsId"] = "053453";
params["ablout"] = "测试";
params["zoom"] = "145";
params["boot"] = "spring";
Map<String,String> newParams = Utils.keySort(params);
String token = Utils.generateToken(newParams);// 获取token
print("需要放到header的token值:$token");
//获取加密后的参数
String aesStr = Utils.encryptAESCbc128WithPadding7(Uri.encodeComponent(json.encode(newParams)));
print("传输给服务器的aes数据:$aesStr");
}
Future<void> _getAccessToken() async {
Response response;
Dio dio = Dio();
response = await dio.post("${Utils.IP}/openapi/getToken", data: {"deviceId": _deviceId});
setState(() {
_response = response.data.toString();
});
}
Future<void> _getDeviceId() async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
setState(() {
_deviceId = androidInfo.androidId;
});
}
}