diff --git a/lib/models/auth/auth_model.dart b/lib/models/auth/auth_model.dart new file mode 100644 index 0000000..4f94dc7 --- /dev/null +++ b/lib/models/auth/auth_model.dart @@ -0,0 +1,27 @@ +import 'package:chat/models/user_info_model.dart'; + +class AuthModel { + String tokenType; + String accessToken; + String userSig; + String userID; + UserInfoModel userInfo; + + String get userToken => '$tokenType $accessToken'; + + AuthModel({ + required this.tokenType, + required this.accessToken, + required this.userID, + required this.userSig, + required this.userInfo, + }); + + factory AuthModel.fromJson(Map json) => AuthModel( + tokenType: json['token_type'], + accessToken: json['access_token'], + userID: json['user_id'], + userSig: json['user_sig'], + userInfo: UserInfoModel.fromJson(json['user_info']), + ); +} diff --git a/lib/providers/auth_provider.dart b/lib/providers/auth_provider.dart new file mode 100644 index 0000000..44e4f94 --- /dev/null +++ b/lib/providers/auth_provider.dart @@ -0,0 +1,21 @@ +import 'package:chat/models/auth/auth_model.dart'; +import 'package:chat/utils/request/http.dart'; +import 'package:chat/utils/ui_tools.dart'; + +class AuthProvider { + static Future login(String address) async { + try { + final result = await Http.post( + 'auth/login', + data: { + 'address': address, + }, + ); + + return AuthModel.fromJson(result); + } catch (e) { + UiTools.toast('区块链地址获取失败'); + return null; + } + } +} diff --git a/lib/services/auth_service.dart b/lib/services/auth_service.dart index 098776a..e05bd17 100644 --- a/lib/services/auth_service.dart +++ b/lib/services/auth_service.dart @@ -1,4 +1,5 @@ import 'package:chat/models/user_info_model.dart'; +import 'package:chat/providers/auth_provider.dart'; import 'package:chat/routes/auth_routes.dart'; import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; @@ -18,10 +19,12 @@ class AuthService extends GetxService { /// 供请求时调用,载入内存,是为了每次使用的时候,不需要从磁盘获取 late String userId = ''; late String userSig = ''; + late String userToken = ''; /// 获取存储的token,这个可以做到持久化存储 - String get _userSig => _box.read('userSig') ?? ''; String get _userId => _box.read('userId') ?? ''; + String get _userSig => _box.read('userSig') ?? ''; + String get _userToken => _box.read('userToken') ?? ''; Rx userInfo = UserInfoModel.empty().obs; @@ -29,27 +32,32 @@ class AuthService extends GetxService { void onInit() { super.onInit(); - if (_userSig.isNotEmpty) { + if (_userToken.isNotEmpty) { isLogin.value = true; userSig = _userSig; userId = _userId; + userToken = _userToken; } - - // ever(_isLogin, (_) { - // if (_ == true) { - // Get.offAllNamed(AppRoutes.app); - // } else { - // Get.offAllNamed(AuthRoutes.index); - // } - // }); } Future login(String address) async { - _box.write('userId', ''); - userId = ''; - isLogin.value = true; + var result = await AuthProvider.login(address); - return true; + if (result != null) { + _box.write('userId', result.userID); + _box.write('userSig', result.userSig); + _box.write('userToken', result.userToken); + + userId = result.userID; + userSig = result.userSig; + userToken = result.userToken; + + isLogin.value = true; + + return true; + } else { + return false; + } } /// 退出登录 @@ -57,8 +65,11 @@ class AuthService extends GetxService { await TencentImSDKPlugin.v2TIMManager.logout(); _box.remove('userSig'); _box.remove('userId'); + _box.remove('userToken'); userSig = ''; userId = ''; + userToken = ''; + userInfo.value = UserInfoModel.empty(); isLogin.value = false; Get.offAllNamed(AuthRoutes.index); diff --git a/lib/utils/crypto_helper.dart b/lib/utils/crypto_helper.dart new file mode 100644 index 0000000..93c4732 --- /dev/null +++ b/lib/utils/crypto_helper.dart @@ -0,0 +1,28 @@ +import 'dart:convert'; + +import 'package:encrypt/encrypt.dart'; +import 'package:crypto/crypto.dart'; + +class CryptoHelper { + static IV iv = IV.fromLength(16); + + /// 初始化加密 + static Encrypter initEncrypter(String password) { + final List bytes = utf8.encode(password); + final Digest md5Bytes = md5.convert(bytes); + final Key key = Key.fromUtf8(md5Bytes.toString()); + return Encrypter(AES(key, mode: AESMode.ecb)); + } + + /// AES 加密 + static String encryptAes(String plainText, String password) { + Encrypter encrypter = CryptoHelper.initEncrypter(password); + return encrypter.encrypt(plainText, iv: iv).base64; + } + + /// AES 解密 + static String decryptAes(String encrypted, String password) { + Encrypter encrypter = CryptoHelper.initEncrypter(password); + return encrypter.decrypt16(encrypted, iv: iv); + } +} diff --git a/lib/utils/request/http_interceptor.dart b/lib/utils/request/http_interceptor.dart index 1470efd..334fec3 100644 --- a/lib/utils/request/http_interceptor.dart +++ b/lib/utils/request/http_interceptor.dart @@ -9,7 +9,7 @@ class HttpInterceptor extends Interceptor { RequestInterceptorHandler handler, ) { // 头部添加token - // options.headers['Authorization'] = AuthService.to.userToken; + options.headers['Authorization'] = AuthService.to.userToken; options.headers['Accept'] = 'application/json'; super.onRequest( diff --git a/lib/views/auth/import/index_page.dart b/lib/views/auth/import/index_page.dart index e10d7a3..a89cfcb 100644 --- a/lib/views/auth/import/index_page.dart +++ b/lib/views/auth/import/index_page.dart @@ -18,6 +18,11 @@ class _AuthImportPageState extends State { @override void initState() { super.initState(); + + setState(() { + _editingController.text = + 'demise sell awesome tragic faith village party elbow lady leopard wrestle civil'; + }); } @override @@ -49,12 +54,14 @@ class _AuthImportPageState extends State { ), const Text('支持导入所有遵循BIP标准生成的助记词'), ElevatedButton( - onPressed: () { + onPressed: () async { String? address = HDWallet.mnemonicToAddress(_editingController.text); if (address != null) { - AuthService.to.login(address); - Get.offAllNamed(AppRoutes.app); + var result = await AuthService.to.login(address); + if (result) { + Get.offAllNamed(AppRoutes.app); + } } }, child: const Text('开始导入'), diff --git a/pubspec.lock b/pubspec.lock index b3e8c94..4e90839 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -15,6 +15,20 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "2.0.2" + args: + dependency: transitive + description: + name: args + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.3.1" + asn1lib: + dependency: transitive + description: + name: asn1lib + url: "https://pub.flutter-io.cn" + source: hosted + version: "1.2.0" async: dependency: transitive description: @@ -164,6 +178,13 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "4.0.6" + encrypt: + dependency: "direct main" + description: + name: encrypt + url: "https://pub.flutter-io.cn" + source: hosted + version: "5.0.1" extended_image: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a918f2c..908aa60 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -48,6 +48,7 @@ dependencies: photo_view: ^0.14.0 photo_manager: 2.2.1 chewie: ^1.3.5 + encrypt: ^5.0.1 dev_dependencies: flutter_test: