diff --git a/lib/http/init.dart b/lib/http/init.dart index 9c0f368c..428cdaba 100644 --- a/lib/http/init.dart +++ b/lib/http/init.dart @@ -1,13 +1,11 @@ // ignore_for_file: avoid_print import 'dart:async'; -import 'dart:developer'; import 'dart:io'; import 'package:cookie_jar/cookie_jar.dart'; import 'package:dio/dio.dart'; import 'package:dio/io.dart'; import 'package:dio_cookie_manager/dio_cookie_manager.dart'; import 'package:hive/hive.dart'; -import 'package:pilipala/models/user/info.dart'; import 'package:pilipala/utils/id_utils.dart'; import '../utils/storage.dart'; import '../utils/utils.dart'; @@ -39,18 +37,7 @@ class Request { dio.interceptors.add(cookieManager); final List cookie = await cookieManager.cookieJar .loadForRequest(Uri.parse(HttpString.baseUrl)); - final UserInfoData? userInfo = userInfoCache.get('userInfoCache'); - if (userInfo != null && userInfo.mid != null) { - final List cookie2 = await cookieManager.cookieJar - .loadForRequest(Uri.parse(HttpString.tUrl)); - if (cookie2.isEmpty) { - try { - await Request().get(HttpString.tUrl); - } catch (e) { - log("setCookie, ${e.toString()}"); - } - } - } + final userInfo = userInfoCache.get('userInfoCache'); setOptionsHeaders(userInfo, userInfo != null && userInfo.mid != null); String baseUrlType = 'default'; if (setting.get(SettingBoxKey.enableGATMode, defaultValue: false)) { @@ -69,10 +56,10 @@ class Request { static Future getCsrf() async { List cookies = await cookieManager.cookieJar .loadForRequest(Uri.parse(HttpString.baseUrl)); - String token = ''; - if (cookies.where((e) => e.name == 'bili_jct').isNotEmpty) { - token = cookies.firstWhere((e) => e.name == 'bili_jct').value; - } + String token = cookies + .firstWhere((e) => e.name == 'bili_jct', + orElse: () => Cookie('bili_jct', '')) + .value; return token; } diff --git a/lib/pages/login/controller.dart b/lib/pages/login/controller.dart index 9e7fb339..b43eda64 100644 --- a/lib/pages/login/controller.dart +++ b/lib/pages/login/controller.dart @@ -1,14 +1,19 @@ import 'dart:async'; import 'dart:io'; +import 'package:cookie_jar/cookie_jar.dart'; +import 'package:dio_cookie_manager/dio_cookie_manager.dart'; import 'package:encrypt/encrypt.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; +import 'package:pilipala/http/constants.dart'; +import 'package:pilipala/http/index.dart'; import 'package:pilipala/http/login.dart'; import 'package:gt3_flutter_plugin/gt3_flutter_plugin.dart'; import 'package:pilipala/models/login/index.dart'; import 'package:pilipala/utils/login.dart'; +import 'package:pilipala/utils/utils.dart'; class LoginPageController extends GetxController { final GlobalKey mobFormKey = GlobalKey(); @@ -341,4 +346,32 @@ class LoginPageController extends GetxController { Get.back(); } } + + // cookie登录 + Future loginInByCookie({ + required String cookiesStr, + String domain = HttpString.baseUrl, + }) async { + final List cookiesStrList = cookiesStr.split('; '); + final List cookiesList = cookiesStrList.map((cookie) { + final cookieArr = cookie.split('='); + return Cookie(cookieArr[0], cookieArr[1]); + }).toList(); + + final String cookiePath = await Utils.getCookiePath(); + final cookieJar = PersistCookieJar( + ignoreExpires: true, + storage: FileStorage(cookiePath), + ); + CookieManager cookieManager = CookieManager(cookieJar); + Request.cookieManager = cookieManager; + await Request.cookieManager.cookieJar + .saveFromResponse(Uri.parse(HttpString.baseUrl), cookiesList); + try { + Request.dio.options.headers['cookie'] = cookiesStr; + } catch (err) { + debugPrint(err.toString()); + } + LoginUtils.confirmLogin('', null); + } } diff --git a/lib/pages/login/view.dart b/lib/pages/login/view.dart index 4fe21792..8ba012ea 100644 --- a/lib/pages/login/view.dart +++ b/lib/pages/login/view.dart @@ -14,6 +14,144 @@ class LoginPage extends StatefulWidget { class _LoginPageState extends State { final LoginPageController _loginPageCtr = Get.put(LoginPageController()); + // 浏览器登录 + void loginInByWeb() { + Get.offNamed( + '/webview', + parameters: { + 'url': 'https://passport.bilibili.com/h5-app/passport/login', + 'type': 'login', + 'pageTitle': '登录bilibili', + }, + ); + } + + // 二维码方式登录 + void loginInByWebQrcode() { + showDialog( + context: context, + builder: (context) { + return StatefulBuilder(builder: (context, StateSetter setState) { + return AlertDialog( + title: Row( + children: [ + const Text('扫码登录'), + IconButton( + onPressed: () { + setState(() {}); + }, + icon: const Icon(Icons.refresh), + ), + ], + ), + contentPadding: const EdgeInsets.fromLTRB(0, 0, 0, 4), + content: AspectRatio( + aspectRatio: 1, + child: Container( + width: 200, + padding: const EdgeInsets.all(12), + child: FutureBuilder( + future: _loginPageCtr.getWebQrcode(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + if (snapshot.data == null) { + return const SizedBox(); + } + Map data = snapshot.data as Map; + return QrImageView( + data: data['data']['url'], + backgroundColor: Colors.white, + ); + } else { + return const Center( + child: SizedBox( + width: 40, + height: 40, + child: CircularProgressIndicator(), + ), + ); + } + }, + ), + ), + ), + actions: [ + TextButton( + onPressed: () {}, + child: Obx(() { + return Text( + '有效期: ${_loginPageCtr.validSeconds.value}s', + style: Theme.of(context).textTheme.titleMedium, + ); + }), + ), + TextButton( + onPressed: () {}, + child: Text( + '检查登录状态', + style: TextStyle( + fontSize: Theme.of(context).textTheme.titleMedium!.fontSize, + ), + ), + ) + ], + ); + }); + }, + ).then((value) { + _loginPageCtr.validTimer!.cancel(); + }); + } + + // cookie登录 + // cookie登录 + void loginInByCookie() async { + var cookies = ''; + final outline = Theme.of(context).colorScheme.outline; + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text('Cookie登录'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text('请将主站cookie粘贴到下方输入框中,点击「确认」即可完成登录。(记得清空粘贴板~)'), + const SizedBox(height: 12), + TextField( + minLines: 1, + maxLines: 3, + decoration: InputDecoration( + labelText: 'cookie', + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(6.0), + ), + ), + onChanged: (e) => cookies = e, + ), + ], + ), + actions: [ + TextButton( + onPressed: Navigator.of(context).pop, + child: Text('取消', style: TextStyle(color: outline))), + TextButton( + onPressed: () async { + if (cookies.isEmpty) { + return; + } + await _loginPageCtr.loginInByCookie(cookiesStr: cookies); + if (context.mounted) { + Navigator.of(context).pop(); + } + }, + child: const Text('确认')) + ], + ); + }, + ); + } + @override void dispose() { _loginPageCtr.validTimer?.cancel(); @@ -43,100 +181,17 @@ class _LoginPageState extends State { actions: [ IconButton( tooltip: '浏览器打开', - onPressed: () { - Get.offNamed( - '/webview', - parameters: { - 'url': 'https://passport.bilibili.com/h5-app/passport/login', - 'type': 'login', - 'pageTitle': '登录bilibili', - }, - ); - }, + onPressed: loginInByWeb, icon: const Icon(Icons.language, size: 20), ), + IconButton( + tooltip: 'cookie登录', + onPressed: loginInByCookie, + icon: const Icon(Icons.cookie_outlined, size: 20), + ), IconButton( tooltip: '二维码登录', - onPressed: () { - showDialog( - context: context, - builder: (context) { - return StatefulBuilder( - builder: (context, StateSetter setState) { - return AlertDialog( - title: Row( - children: [ - const Text('扫码登录'), - IconButton( - onPressed: () { - setState(() {}); - }, - icon: const Icon(Icons.refresh), - ), - ], - ), - contentPadding: const EdgeInsets.fromLTRB(0, 0, 0, 4), - content: AspectRatio( - aspectRatio: 1, - child: Container( - width: 200, - padding: const EdgeInsets.all(12), - child: FutureBuilder( - future: _loginPageCtr.getWebQrcode(), - builder: (context, snapshot) { - if (snapshot.connectionState == - ConnectionState.done) { - if (snapshot.data == null) { - return const SizedBox(); - } - Map data = snapshot.data as Map; - return QrImageView( - data: data['data']['url'], - backgroundColor: Colors.white, - ); - } else { - return const Center( - child: SizedBox( - width: 40, - height: 40, - child: CircularProgressIndicator(), - ), - ); - } - }, - ), - ), - ), - actions: [ - TextButton( - onPressed: () {}, - child: Obx(() { - return Text( - '有效期: ${_loginPageCtr.validSeconds.value}s', - style: Theme.of(context).textTheme.titleMedium, - ); - }), - ), - TextButton( - onPressed: () {}, - child: Text( - '检查登录状态', - style: TextStyle( - fontSize: Theme.of(context) - .textTheme - .titleMedium! - .fontSize, - ), - ), - ) - ], - ); - }); - }, - ).then((value) { - _loginPageCtr.validTimer!.cancel(); - }); - }, + onPressed: loginInByWebQrcode, icon: const Icon(Icons.qr_code, size: 20), ), const SizedBox(width: 22), diff --git a/lib/utils/login.dart b/lib/utils/login.dart index 159de81d..e9fde1f2 100644 --- a/lib/utils/login.dart +++ b/lib/utils/login.dart @@ -12,7 +12,6 @@ import 'package:pilipala/http/user.dart'; import 'package:pilipala/pages/dynamics/index.dart'; import 'package:pilipala/pages/home/index.dart'; import 'package:pilipala/pages/mine/index.dart'; -import 'package:pilipala/utils/cookie.dart'; import 'package:pilipala/utils/global_data_cache.dart'; import 'package:pilipala/utils/storage.dart'; import 'package:uuid/uuid.dart'; @@ -68,7 +67,6 @@ class LoginUtils { content = '${content + url}; \n'; } try { - await SetCookie.onSet(); final result = await UserHttp.userInfo(); if (result['status'] && result['data'].isLogin) { SmartDialog.showToast('登录成功');