Merge branch 'feature-cookies'
This commit is contained in:
@ -1,13 +1,11 @@
|
|||||||
// ignore_for_file: avoid_print
|
// ignore_for_file: avoid_print
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:developer';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:cookie_jar/cookie_jar.dart';
|
import 'package:cookie_jar/cookie_jar.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:dio/io.dart';
|
import 'package:dio/io.dart';
|
||||||
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
|
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:pilipala/models/user/info.dart';
|
|
||||||
import 'package:pilipala/utils/id_utils.dart';
|
import 'package:pilipala/utils/id_utils.dart';
|
||||||
import '../utils/storage.dart';
|
import '../utils/storage.dart';
|
||||||
import '../utils/utils.dart';
|
import '../utils/utils.dart';
|
||||||
@ -39,18 +37,7 @@ class Request {
|
|||||||
dio.interceptors.add(cookieManager);
|
dio.interceptors.add(cookieManager);
|
||||||
final List<Cookie> cookie = await cookieManager.cookieJar
|
final List<Cookie> cookie = await cookieManager.cookieJar
|
||||||
.loadForRequest(Uri.parse(HttpString.baseUrl));
|
.loadForRequest(Uri.parse(HttpString.baseUrl));
|
||||||
final UserInfoData? userInfo = userInfoCache.get('userInfoCache');
|
final userInfo = userInfoCache.get('userInfoCache');
|
||||||
if (userInfo != null && userInfo.mid != null) {
|
|
||||||
final List<Cookie> cookie2 = await cookieManager.cookieJar
|
|
||||||
.loadForRequest(Uri.parse(HttpString.tUrl));
|
|
||||||
if (cookie2.isEmpty) {
|
|
||||||
try {
|
|
||||||
await Request().get(HttpString.tUrl);
|
|
||||||
} catch (e) {
|
|
||||||
log("setCookie, ${e.toString()}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setOptionsHeaders(userInfo, userInfo != null && userInfo.mid != null);
|
setOptionsHeaders(userInfo, userInfo != null && userInfo.mid != null);
|
||||||
String baseUrlType = 'default';
|
String baseUrlType = 'default';
|
||||||
if (setting.get(SettingBoxKey.enableGATMode, defaultValue: false)) {
|
if (setting.get(SettingBoxKey.enableGATMode, defaultValue: false)) {
|
||||||
@ -69,10 +56,10 @@ class Request {
|
|||||||
static Future<String> getCsrf() async {
|
static Future<String> getCsrf() async {
|
||||||
List<Cookie> cookies = await cookieManager.cookieJar
|
List<Cookie> cookies = await cookieManager.cookieJar
|
||||||
.loadForRequest(Uri.parse(HttpString.baseUrl));
|
.loadForRequest(Uri.parse(HttpString.baseUrl));
|
||||||
String token = '';
|
String token = cookies
|
||||||
if (cookies.where((e) => e.name == 'bili_jct').isNotEmpty) {
|
.firstWhere((e) => e.name == 'bili_jct',
|
||||||
token = cookies.firstWhere((e) => e.name == 'bili_jct').value;
|
orElse: () => Cookie('bili_jct', ''))
|
||||||
}
|
.value;
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
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:encrypt/encrypt.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.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:pilipala/http/login.dart';
|
||||||
import 'package:gt3_flutter_plugin/gt3_flutter_plugin.dart';
|
import 'package:gt3_flutter_plugin/gt3_flutter_plugin.dart';
|
||||||
import 'package:pilipala/models/login/index.dart';
|
import 'package:pilipala/models/login/index.dart';
|
||||||
import 'package:pilipala/utils/login.dart';
|
import 'package:pilipala/utils/login.dart';
|
||||||
|
import 'package:pilipala/utils/utils.dart';
|
||||||
|
|
||||||
class LoginPageController extends GetxController {
|
class LoginPageController extends GetxController {
|
||||||
final GlobalKey mobFormKey = GlobalKey<FormState>();
|
final GlobalKey mobFormKey = GlobalKey<FormState>();
|
||||||
@ -341,4 +346,32 @@ class LoginPageController extends GetxController {
|
|||||||
Get.back();
|
Get.back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// cookie登录
|
||||||
|
Future loginInByCookie({
|
||||||
|
required String cookiesStr,
|
||||||
|
String domain = HttpString.baseUrl,
|
||||||
|
}) async {
|
||||||
|
final List<String> cookiesStrList = cookiesStr.split('; ');
|
||||||
|
final List<Cookie> 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,144 @@ class LoginPage extends StatefulWidget {
|
|||||||
class _LoginPageState extends State<LoginPage> {
|
class _LoginPageState extends State<LoginPage> {
|
||||||
final LoginPageController _loginPageCtr = Get.put(LoginPageController());
|
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
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_loginPageCtr.validTimer?.cancel();
|
_loginPageCtr.validTimer?.cancel();
|
||||||
@ -43,100 +181,17 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: '浏览器打开',
|
tooltip: '浏览器打开',
|
||||||
onPressed: () {
|
onPressed: loginInByWeb,
|
||||||
Get.offNamed(
|
|
||||||
'/webview',
|
|
||||||
parameters: {
|
|
||||||
'url': 'https://passport.bilibili.com/h5-app/passport/login',
|
|
||||||
'type': 'login',
|
|
||||||
'pageTitle': '登录bilibili',
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.language, size: 20),
|
icon: const Icon(Icons.language, size: 20),
|
||||||
),
|
),
|
||||||
|
IconButton(
|
||||||
|
tooltip: 'cookie登录',
|
||||||
|
onPressed: loginInByCookie,
|
||||||
|
icon: const Icon(Icons.cookie_outlined, size: 20),
|
||||||
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
tooltip: '二维码登录',
|
tooltip: '二维码登录',
|
||||||
onPressed: () {
|
onPressed: 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();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.qr_code, size: 20),
|
icon: const Icon(Icons.qr_code, size: 20),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 22),
|
const SizedBox(width: 22),
|
||||||
|
@ -12,7 +12,6 @@ import 'package:pilipala/http/user.dart';
|
|||||||
import 'package:pilipala/pages/dynamics/index.dart';
|
import 'package:pilipala/pages/dynamics/index.dart';
|
||||||
import 'package:pilipala/pages/home/index.dart';
|
import 'package:pilipala/pages/home/index.dart';
|
||||||
import 'package:pilipala/pages/mine/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/global_data_cache.dart';
|
||||||
import 'package:pilipala/utils/storage.dart';
|
import 'package:pilipala/utils/storage.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
@ -68,7 +67,6 @@ class LoginUtils {
|
|||||||
content = '${content + url}; \n';
|
content = '${content + url}; \n';
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await SetCookie.onSet();
|
|
||||||
final result = await UserHttp.userInfo();
|
final result = await UserHttp.userInfo();
|
||||||
if (result['status'] && result['data'].isLogin) {
|
if (result['status'] && result['data'].isLogin) {
|
||||||
SmartDialog.showToast('登录成功');
|
SmartDialog.showToast('登录成功');
|
||||||
|
Reference in New Issue
Block a user