mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-30 14:20:15 +08:00
feat: 新版登录页:以APP接口和新界面全面重构网页版登录;更新二维码与极验插件;更新版本号
This commit is contained in:
@@ -462,12 +462,19 @@ class Api {
|
||||
// web端验证码登录
|
||||
|
||||
// web端密码登录
|
||||
static const String logInByWebPwd =
|
||||
'${HttpString.passBaseUrl}/x/passport-login/web/login';
|
||||
|
||||
// 获取guestID
|
||||
// static const String getGuestId = '/x/passport-user/guest/reg';
|
||||
|
||||
// app端短信验证码
|
||||
static const String appSmsCode =
|
||||
'${HttpString.passBaseUrl}/x/passport-login/sms/send';
|
||||
|
||||
// app端验证码登录
|
||||
static const String logInByAppSms =
|
||||
'${HttpString.passBaseUrl}/x/passport-login/login/sms';
|
||||
|
||||
// 获取短信验证码
|
||||
// static const String appSafeSmsCode =
|
||||
@@ -477,8 +484,8 @@ class Api {
|
||||
/// username
|
||||
/// password
|
||||
/// key
|
||||
/// rhash
|
||||
static const String loginInByPwdApi =
|
||||
/// salt
|
||||
static const String loginByPwdApi =
|
||||
'${HttpString.passBaseUrl}/x/passport-login/oauth2/login';
|
||||
|
||||
/// 密码加密密钥
|
||||
|
||||
@@ -3,43 +3,42 @@
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import '../utils/storage.dart';
|
||||
|
||||
class ApiInterceptor extends Interceptor {
|
||||
@override
|
||||
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||
// print("请求之前");
|
||||
// 在请求之前添加头部或认证信息
|
||||
// options.headers['Authorization'] = 'Bearer token';
|
||||
// options.headers['Content-Type'] = 'application/json';
|
||||
handler.next(options);
|
||||
}
|
||||
// @override
|
||||
// void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||
// print("请求之前");
|
||||
// // 在请求之前添加头部或认证信息
|
||||
// options.headers['Authorization'] = 'Bearer token';
|
||||
// options.headers['Content-Type'] = 'application/json';
|
||||
// handler.next(options);
|
||||
// }
|
||||
|
||||
@override
|
||||
void onResponse(Response response, ResponseInterceptorHandler handler) {
|
||||
try {
|
||||
if (response.statusCode == 302) {
|
||||
final List<String> locations = response.headers['location']!;
|
||||
if (locations.isNotEmpty) {
|
||||
if (locations.first.startsWith('https://www.mcbbs.net')) {
|
||||
final Uri uri = Uri.parse(locations.first);
|
||||
final String? accessKey = uri.queryParameters['access_key'];
|
||||
final String? mid = uri.queryParameters['mid'];
|
||||
try {
|
||||
Box localCache = GStorage.localCache;
|
||||
localCache.put(LocalCacheKey.accessKey,
|
||||
<String, String?>{'mid': mid, 'value': accessKey});
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
print('ApiInterceptor: $err');
|
||||
}
|
||||
// @override
|
||||
// void onResponse(Response response, ResponseInterceptorHandler handler) {
|
||||
// try {
|
||||
// if (response.statusCode == 302) {
|
||||
// final List<String> locations = response.headers['location']!;
|
||||
// if (locations.isNotEmpty) {
|
||||
// if (locations.first.startsWith('https://www.mcbbs.net')) {
|
||||
// print('ApiInterceptor@@@@@: ${locations.first}');
|
||||
// final Uri uri = Uri.parse(locations.first);
|
||||
// final String? accessKey = uri.queryParameters['access_key'];
|
||||
// final String? mid = uri.queryParameters['mid'];
|
||||
// try {
|
||||
// Box localCache = GStorage.localCache;
|
||||
// localCache.put(LocalCacheKey.accessKey,
|
||||
// <String, String?>{'mid': mid, 'value': accessKey});
|
||||
// } catch (_) {}
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } catch (err) {
|
||||
// print('ApiInterceptor: $err');
|
||||
// }
|
||||
|
||||
handler.next(response);
|
||||
}
|
||||
// handler.next(response);
|
||||
// }
|
||||
|
||||
@override
|
||||
void onError(DioException err, ErrorInterceptorHandler handler) async {
|
||||
|
||||
@@ -3,12 +3,68 @@ import 'dart:math';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:encrypt/encrypt.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import '../common/constants.dart';
|
||||
import '../models/login/index.dart';
|
||||
import '../utils/login.dart';
|
||||
import '../utils/utils.dart';
|
||||
import 'index.dart';
|
||||
|
||||
class LoginHttp {
|
||||
static String deviceId = genDeviceId();
|
||||
static String buvid = genBuvid();
|
||||
static String host = 'passport.bilibili.com';
|
||||
static String traceId =
|
||||
'11111111111111111111111111111111:1111111111111111:0:0';
|
||||
static String statistics = Uri.encodeComponent(
|
||||
'{"appId": 5,"platform": 3,"version": "1.46.2","abtest": ""}');
|
||||
static String userAgent =
|
||||
'Mozilla/5.0 BiliDroid/1.46.2 (bbcallen@gmail.com) os/android model/vivo mobi_app/android_hd build/1462100 channel/yingyongbao innerVer/1462100 osVer/14 network/2';
|
||||
static Future<Map<String, dynamic>> getHDcode() async {
|
||||
var params = {
|
||||
'appkey': Constants.appKey,
|
||||
// 'local_id': 'Y952A395BB157D305D8A8340FC2AAECECE17',
|
||||
'local_id': '0',
|
||||
//精确到秒的时间戳
|
||||
'ts': (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(),
|
||||
'platform': 'android',
|
||||
'mobi_app': 'android_hd',
|
||||
};
|
||||
String sign = Utils.appSign(
|
||||
params,
|
||||
Constants.appKey,
|
||||
Constants.appSec,
|
||||
);
|
||||
var res = await Request()
|
||||
.post(Api.getTVCode, queryParameters: {...params, 'sign': sign});
|
||||
print(res);
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'data': res.data['data']};
|
||||
} else {
|
||||
return {'status': false, 'msg': res.data['message']};
|
||||
}
|
||||
}
|
||||
|
||||
static Future codePoll(String authCode) async {
|
||||
var params = {
|
||||
'appkey': Constants.appKey,
|
||||
'auth_code': authCode,
|
||||
'local_id': '0',
|
||||
'ts': (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(),
|
||||
};
|
||||
String sign = Utils.appSign(
|
||||
params,
|
||||
Constants.appKey,
|
||||
Constants.appSec,
|
||||
);
|
||||
var res = await Request()
|
||||
.post(Api.qrcodePoll, queryParameters: {...params, 'sign': sign});
|
||||
return {
|
||||
'status': res.data['code'] == 0,
|
||||
'code': res.data['code'],
|
||||
'data': res.data['data'],
|
||||
'msg': res.data['message']
|
||||
};
|
||||
}
|
||||
|
||||
static Future queryCaptcha() async {
|
||||
var res = await Request().get(Api.getCaptcha);
|
||||
if (res.data['code'] == 0) {
|
||||
@@ -21,107 +77,141 @@ class LoginHttp {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取salt与PubKey
|
||||
static Future getWebKey() async {
|
||||
var res = await Request().get(Api.getWebKey);
|
||||
//data: {'disable_rcmd': 0, 'local_id': LoginUtils.generateBuvid()});
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'data': res.data['data']};
|
||||
} else {
|
||||
return {'status': false, 'data': {}, 'msg': res.data['message']};
|
||||
}
|
||||
}
|
||||
|
||||
static Future sendSmsCode({
|
||||
int? cid,
|
||||
required int tel,
|
||||
required String token,
|
||||
required String challenge,
|
||||
required String validate,
|
||||
required String seccode,
|
||||
required String cid,
|
||||
required String tel,
|
||||
// String? deviceTouristId,
|
||||
String? gee_challenge,
|
||||
String? gee_seccode,
|
||||
String? gee_validate,
|
||||
String? recaptcha_token,
|
||||
}) async {
|
||||
int timestamp = DateTime.now().millisecondsSinceEpoch;
|
||||
var data = {
|
||||
'appkey': Constants.appKey,
|
||||
'build': '1462100',
|
||||
'buvid': buvid,
|
||||
'c_locale': 'zh_CN',
|
||||
'cid': cid,
|
||||
// if (deviceTouristId != null) 'device_tourist_id': deviceTouristId,
|
||||
'disable_rcmd': '0',
|
||||
if (gee_challenge != null) 'gee_challenge': gee_challenge,
|
||||
if (gee_seccode != null) 'gee_seccode': gee_seccode,
|
||||
if (gee_validate != null) 'gee_validate': gee_validate,
|
||||
'local_id': buvid,
|
||||
// https://chinggg.github.io/post/appre/
|
||||
'login_session_id':
|
||||
md5.convert(utf8.encode(buvid + timestamp.toString())).toString(),
|
||||
'mobi_app': 'android_hd',
|
||||
'platform': 'android',
|
||||
if (recaptcha_token != null) 'recaptcha_token': recaptcha_token,
|
||||
's_locale': 'zh_CN',
|
||||
'statistics': statistics,
|
||||
'tel': tel,
|
||||
'ts': (timestamp ~/ 1000).toString(),
|
||||
};
|
||||
String sign = Utils.appSign(
|
||||
data,
|
||||
Constants.appKey,
|
||||
Constants.appSec,
|
||||
);
|
||||
var headers = {
|
||||
'Host': host,
|
||||
'buvid': buvid,
|
||||
'env': 'prod',
|
||||
'app-key': 'android_hd',
|
||||
'user-agent': userAgent,
|
||||
'x-bili-trace-id': traceId,
|
||||
'x-bili-aurora-eid': '',
|
||||
'x-bili-aurora-zone': '',
|
||||
'bili-http-engine': 'cronet',
|
||||
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
|
||||
};
|
||||
|
||||
var res = await Request().post(
|
||||
Api.appSmsCode,
|
||||
data: {
|
||||
'cid': cid,
|
||||
'tel': tel,
|
||||
"source": "main_web",
|
||||
'token': token,
|
||||
'challenge': challenge,
|
||||
'validate': validate,
|
||||
'seccode': seccode,
|
||||
},
|
||||
data: {...data, 'sign': sign},
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
// headers: {'user-agent': ApiConstants.userAgent}
|
||||
headers: headers,
|
||||
),
|
||||
);
|
||||
print(res);
|
||||
if (res.data['code'] == 0 && res.data['data']['recaptcha_url'] == "") {
|
||||
return {'status': true, 'data': res.data['data']};
|
||||
} else {
|
||||
return {
|
||||
'status': false,
|
||||
'code': res.data['code'],
|
||||
'msg': res.data['message'],
|
||||
'data': res.data['data']
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// web端验证码
|
||||
static Future sendWebSmsCode({
|
||||
int? cid,
|
||||
required int tel,
|
||||
required String token,
|
||||
required String challenge,
|
||||
required String validate,
|
||||
required String seccode,
|
||||
}) async {
|
||||
Map data = {
|
||||
'cid': cid,
|
||||
'tel': tel,
|
||||
'token': token,
|
||||
'challenge': challenge,
|
||||
'validate': validate,
|
||||
'seccode': seccode,
|
||||
};
|
||||
FormData formData = FormData.fromMap({...data});
|
||||
var res = await Request().post(
|
||||
Api.smsCode,
|
||||
data: formData,
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
),
|
||||
);
|
||||
print(res);
|
||||
}
|
||||
// static Future getGuestId(String key) async {
|
||||
// dynamic publicKey = RSAKeyParser().parse(key);
|
||||
// var params = {
|
||||
// 'appkey': Constants.appKey,
|
||||
// 'build': '1462100',
|
||||
// 'buvid': buvid,
|
||||
// 'c_locale': 'zh_CN',
|
||||
// 'channel': 'yingyongbao',
|
||||
// 'deviceInfo': 'xxxxxx',
|
||||
// 'disable_rcmd': '0',
|
||||
// 'dt': Uri.encodeComponent(Encrypter(RSA(publicKey: publicKey))
|
||||
// .encrypt(generateRandomString(16))
|
||||
// .base64),
|
||||
// 'local_id': buvid,
|
||||
// 'mobi_app': 'android_hd',
|
||||
// 'platform': 'android',
|
||||
// 's_locale': 'zh_CN',
|
||||
// 'statistics': statistics,
|
||||
// 'ts': (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(),
|
||||
// };
|
||||
// String sign = Utils.appSign(
|
||||
// params,
|
||||
// Constants.appKey,
|
||||
// Constants.appSec,
|
||||
// );
|
||||
// var headers = {
|
||||
// 'Host': host,
|
||||
// 'buvid': buvid,
|
||||
// 'env': 'prod',
|
||||
// 'app-key': 'android_hd',
|
||||
// 'user-agent': userAgent,
|
||||
// 'x-bili-trace-id': traceId,
|
||||
// 'x-bili-aurora-eid': '',
|
||||
// 'x-bili-aurora-zone': '',
|
||||
// 'bili-http-engine': 'cronet',
|
||||
// 'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
|
||||
// };
|
||||
// var res = await Request().post(Api.getGuestId,
|
||||
// queryParameters: {...params, 'sign': sign},
|
||||
// options: Options(
|
||||
// contentType: Headers.formUrlEncodedContentType,
|
||||
// headers: headers,
|
||||
// ));
|
||||
// print("getGuestId: $res");
|
||||
// if (res.data['code'] == 0) {
|
||||
// return {'status': true, 'data': res.data['data']};
|
||||
// } else {
|
||||
// return {'status': false, 'msg': res.data['message']};
|
||||
// }
|
||||
// }
|
||||
|
||||
// web端验证码登录
|
||||
static Future loginInByWebSmsCode() async {}
|
||||
|
||||
// web端密码登录
|
||||
static Future liginInByWebPwd() async {}
|
||||
|
||||
// app端验证码
|
||||
static Future sendAppSmsCode({
|
||||
int? cid,
|
||||
required int tel,
|
||||
required String token,
|
||||
required String challenge,
|
||||
required String validate,
|
||||
required String seccode,
|
||||
}) async {
|
||||
Map<String, dynamic> data = {
|
||||
'cid': cid,
|
||||
'tel': tel,
|
||||
'login_session_id': const Uuid().v4().replaceAll('-', ''),
|
||||
'recaptcha_token': token,
|
||||
'gee_challenge': challenge,
|
||||
'gee_validate': validate,
|
||||
'gee_seccode': seccode,
|
||||
'channel': 'bili',
|
||||
'buvid': buvid(),
|
||||
'local_id': buvid(),
|
||||
// 'ts': DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
'statistics': {
|
||||
"appId": 1,
|
||||
"platform": 3,
|
||||
"version": "7.52.0",
|
||||
"abtest": ""
|
||||
},
|
||||
};
|
||||
// FormData formData = FormData.fromMap({...data});
|
||||
var res = await Request().post(
|
||||
Api.appSmsCode,
|
||||
data: data,
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
),
|
||||
);
|
||||
print(res);
|
||||
}
|
||||
|
||||
static String buvid() {
|
||||
static String genBuvid() {
|
||||
var mac = <String>[];
|
||||
var random = Random();
|
||||
|
||||
@@ -137,40 +227,215 @@ class LoginHttp {
|
||||
return 'XY${md5Arr[2]}${md5Arr[12]}${md5Arr[22]}$md5Str';
|
||||
}
|
||||
|
||||
// 获取盐hash跟PubKey
|
||||
static Future getWebKey() async {
|
||||
var res = await Request().get(Api.getWebKey,
|
||||
data: {'disable_rcmd': 0, 'local_id': LoginUtils.generateBuvid()});
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'data': res.data['data']};
|
||||
} else {
|
||||
return {'status': false, 'data': {}, 'msg': res.data['message']};
|
||||
}
|
||||
static String genDeviceId() {
|
||||
// https://github.com/bilive/bilive_client/blob/2873de0532c54832f5464a4c57325ad9af8b8698/bilive/lib/app_client.ts#L62
|
||||
final String yyyyMMddHHmmss = DateTime.now()
|
||||
.toIso8601String()
|
||||
.replaceAll(RegExp(r'[-:TZ]'), '')
|
||||
.substring(0, 14);
|
||||
|
||||
final Random random = Random(); // Random.secure();
|
||||
final String randomHex32 =
|
||||
List.generate(32, (index) => random.nextInt(16).toRadixString(16))
|
||||
.join();
|
||||
final String randomHex16 =
|
||||
List.generate(16, (index) => random.nextInt(16).toRadixString(16))
|
||||
.join();
|
||||
|
||||
final String deviceID = randomHex32 + yyyyMMddHHmmss + randomHex16;
|
||||
|
||||
final List<int> bytes = RegExp(r'\w{2}')
|
||||
.allMatches(deviceID)
|
||||
.map((match) => int.parse(match.group(0)!, radix: 16))
|
||||
.toList();
|
||||
final int checksumValue = bytes.reduce((a, b) => a + b);
|
||||
final String check = checksumValue
|
||||
.toRadixString(16)
|
||||
.substring(checksumValue.toRadixString(16).length - 2);
|
||||
|
||||
return deviceID + check;
|
||||
}
|
||||
|
||||
static String generateRandomString(int length) {
|
||||
const chars =
|
||||
'123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
||||
final Random random = Random(); // Random.secure();
|
||||
return List.generate(length, (index) => chars[random.nextInt(chars.length)])
|
||||
.join();
|
||||
}
|
||||
|
||||
// app端密码登录
|
||||
static Future loginInByMobPwd({
|
||||
required String tel,
|
||||
static Future loginByPwd({
|
||||
required String username,
|
||||
required String password,
|
||||
required String key,
|
||||
required String rhash,
|
||||
required String salt,
|
||||
String? gee_challenge,
|
||||
String? gee_seccode,
|
||||
String? gee_validate,
|
||||
String? recaptcha_token,
|
||||
}) async {
|
||||
dynamic publicKey = RSAKeyParser().parse(key);
|
||||
String passwordEncryptyed =
|
||||
Encrypter(RSA(publicKey: publicKey)).encrypt(rhash + password).base64;
|
||||
print(publicKey);
|
||||
String passwordEncrypted =
|
||||
Encrypter(RSA(publicKey: publicKey)).encrypt(salt + password).base64;
|
||||
|
||||
Map<String, dynamic> data = {
|
||||
'username': tel,
|
||||
'password': passwordEncryptyed,
|
||||
'local_id': LoginUtils.generateBuvid(),
|
||||
'disable_rcmd': "0",
|
||||
'appkey': Constants.appKey,
|
||||
'bili_local_id': deviceId,
|
||||
'build': '1462100',
|
||||
'buvid': buvid,
|
||||
'c_locale': 'zh_CN',
|
||||
'channel': 'yingyongbao',
|
||||
'device': 'phone',
|
||||
'device_id': deviceId,
|
||||
//'device_meta': '',
|
||||
'device_name': 'vivo',
|
||||
'device_platform': 'Android14vivo',
|
||||
'disable_rcmd': '0',
|
||||
'dt': Uri.encodeComponent(Encrypter(RSA(publicKey: publicKey))
|
||||
.encrypt(generateRandomString(16))
|
||||
.base64),
|
||||
'from_pv': 'main.homepage.avatar-nologin.all.click',
|
||||
'from_url': Uri.encodeComponent('bilibili://pegasus/promo'),
|
||||
if (gee_challenge != null) 'gee_challenge': gee_challenge,
|
||||
if (gee_seccode != null) 'gee_seccode': gee_seccode,
|
||||
if (gee_validate != null) 'gee_validate': gee_validate,
|
||||
'local_id': buvid, //LoginUtils.generateBuvid(),
|
||||
'mobi_app': 'android_hd',
|
||||
'password': passwordEncrypted,
|
||||
'permission': 'ALL',
|
||||
'platform': 'android',
|
||||
if (recaptcha_token != null) 'recaptcha_token': recaptcha_token,
|
||||
's_locale': 'zh_CN',
|
||||
'statistics': statistics,
|
||||
'ts': (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(),
|
||||
'username': username,
|
||||
};
|
||||
String sign = Utils.appSign(
|
||||
data,
|
||||
Constants.appKey,
|
||||
Constants.appSec,
|
||||
);
|
||||
data['sign'] = sign;
|
||||
data.map((key, value) {
|
||||
print('$key: $value');
|
||||
return MapEntry<String, dynamic>(key, value);
|
||||
});
|
||||
final Map<String, String> headers = {
|
||||
'Host': host,
|
||||
'buvid': buvid,
|
||||
'env': 'prod',
|
||||
'app-key': 'android_hd',
|
||||
'user-agent': userAgent,
|
||||
'x-bili-trace-id': traceId,
|
||||
'x-bili-aurora-eid': '',
|
||||
'x-bili-aurora-zone': '',
|
||||
'bili-http-engine': 'cronet',
|
||||
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
|
||||
};
|
||||
var res = await Request().post(
|
||||
Api.loginInByPwdApi,
|
||||
Api.loginByPwdApi,
|
||||
data: data,
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
headers: headers,
|
||||
//responseType: ResponseType.plain
|
||||
),
|
||||
);
|
||||
print(res);
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'data': res.data['data']};
|
||||
} else {
|
||||
return {
|
||||
'status': false,
|
||||
'code': res.data['code'],
|
||||
'msg': res.data['message'],
|
||||
'data': res.data['data']
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// app端短信验证码登录
|
||||
static Future loginBySms({
|
||||
required String captchaKey,
|
||||
required String tel,
|
||||
required String code,
|
||||
required String cid,
|
||||
required String key,
|
||||
}) async {
|
||||
dynamic publicKey = RSAKeyParser().parse(key);
|
||||
Map<String, dynamic> data = {
|
||||
'appkey': Constants.appKey,
|
||||
'bili_local_id': deviceId,
|
||||
'build': '1462100',
|
||||
'buvid': buvid,
|
||||
'c_locale': 'zh_CN',
|
||||
'captcha_key': captchaKey,
|
||||
'channel': 'yingyongbao',
|
||||
'cid': cid,
|
||||
'code': code,
|
||||
'device': 'phone',
|
||||
'device_id': deviceId,
|
||||
//'device_meta': '',
|
||||
'device_name': 'vivo',
|
||||
'device_platform': 'Android14vivo',
|
||||
// 'device_tourist_id': '',
|
||||
'disable_rcmd': '0',
|
||||
'dt': Uri.encodeComponent(Encrypter(RSA(publicKey: publicKey))
|
||||
.encrypt(generateRandomString(16))
|
||||
.base64),
|
||||
'from_pv': 'main.my-information.my-login.0.click',
|
||||
'from_url': Uri.encodeComponent('bilibili://user_center/mine'),
|
||||
'local_id': buvid,
|
||||
'mobi_app': 'android_hd',
|
||||
'platform': 'android',
|
||||
's_locale': 'zh_CN',
|
||||
'statistics': statistics,
|
||||
'tel': tel,
|
||||
'ts': (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(),
|
||||
};
|
||||
String sign = Utils.appSign(
|
||||
data,
|
||||
Constants.appKey,
|
||||
Constants.appSec,
|
||||
);
|
||||
data['sign'] = sign;
|
||||
data.map((key, value) {
|
||||
print('$key: $value');
|
||||
return MapEntry<String, dynamic>(key, value);
|
||||
});
|
||||
final Map<String, String> headers = {
|
||||
'Host': host,
|
||||
'buvid': buvid,
|
||||
'env': 'prod',
|
||||
'app-key': 'android_hd',
|
||||
'user-agent': userAgent,
|
||||
'x-bili-trace-id': traceId,
|
||||
'x-bili-aurora-eid': '',
|
||||
'x-bili-aurora-zone': '',
|
||||
'bili-http-engine': 'cronet',
|
||||
'content-type': 'application/x-www-form-urlencoded; charset=utf-8',
|
||||
};
|
||||
var res = await Request().post(
|
||||
Api.logInByAppSms,
|
||||
data: data,
|
||||
options: Options(
|
||||
contentType: Headers.formUrlEncodedContentType,
|
||||
headers: headers,
|
||||
//responseType: ResponseType.plain
|
||||
),
|
||||
);
|
||||
print(res);
|
||||
if (res.data['code'] == 0) {
|
||||
return {'status': true, 'data': res.data['data']};
|
||||
} else {
|
||||
return {
|
||||
'status': false,
|
||||
'code': res.data['code'],
|
||||
'msg': res.data['message'],
|
||||
'data': res.data['data']
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import '../common/constants.dart';
|
||||
import '../models/dynamics/result.dart';
|
||||
import '../models/follow/result.dart';
|
||||
import '../models/member/archive.dart';
|
||||
@@ -8,7 +5,6 @@ import '../models/member/coin.dart';
|
||||
import '../models/member/info.dart';
|
||||
import '../models/member/seasons.dart';
|
||||
import '../models/member/tags.dart';
|
||||
import '../utils/storage.dart';
|
||||
import '../utils/utils.dart';
|
||||
import '../utils/wbi_sign.dart';
|
||||
import 'index.dart';
|
||||
@@ -375,125 +371,6 @@ class MemberHttp {
|
||||
}
|
||||
}
|
||||
|
||||
// 获取TV authCode
|
||||
static Future getTVCode() async {
|
||||
SmartDialog.showLoading(msg: "正在申请HD版二维码...");
|
||||
var params = {
|
||||
'appkey': Constants.appKey,
|
||||
// 'local_id': 'Y952A395BB157D305D8A8340FC2AAECECE17',
|
||||
'local_id': '0',
|
||||
'ts': DateTime.now().millisecondsSinceEpoch.toString(),
|
||||
'platform': 'android',
|
||||
'mobi_app': 'android_hd',
|
||||
};
|
||||
String sign = Utils.appSign(
|
||||
params,
|
||||
Constants.appKey,
|
||||
Constants.appSec,
|
||||
);
|
||||
var res = await Request()
|
||||
.post(Api.getTVCode, queryParameters: {...params, 'sign': sign});
|
||||
SmartDialog.dismiss();
|
||||
print(res.data);
|
||||
if (res.data['code'] == 0) {
|
||||
print("getTVCode");
|
||||
return {
|
||||
'status': true,
|
||||
'data': res.data['data']['auth_code'],
|
||||
'msg': '操作成功'
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
'status': false,
|
||||
'data': [],
|
||||
'msg': res.data,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 获取access_key
|
||||
static Future cookieToKey() async {
|
||||
var authCodeRes = await getTVCode();
|
||||
if (authCodeRes['status']) {
|
||||
SmartDialog.showLoading(msg: "正在确认登录...");
|
||||
var confirmRes =
|
||||
await Request().post(Api.qrcodeConfirm, queryParameters: {
|
||||
'auth_code': authCodeRes['data'],
|
||||
'local_id': '0',
|
||||
'build': 1442100,
|
||||
'scanning_type': 1,
|
||||
'csrf': await Request.getCsrf(),
|
||||
});
|
||||
print("confirmRes");
|
||||
print(confirmRes);
|
||||
SmartDialog.dismiss();
|
||||
if (confirmRes.data['code'] != 0) {
|
||||
return {
|
||||
'status': false,
|
||||
'data': [],
|
||||
'msg':
|
||||
"确认登录失败:${confirmRes.data['message']}\n\n请在设置中退出账号,重启app,重新登录再试",
|
||||
};
|
||||
}
|
||||
SmartDialog.showLoading(msg: "等待500毫秒...");
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
SmartDialog.dismiss();
|
||||
SmartDialog.showLoading(msg: "正在获取登录结果(含access_key)...");
|
||||
var res = await qrcodePoll(authCodeRes['data']);
|
||||
SmartDialog.dismiss();
|
||||
if (res['status']) {
|
||||
return {'status': true, 'data': [], 'msg': res['msg']};
|
||||
} else {
|
||||
return {
|
||||
'status': false,
|
||||
'data': [],
|
||||
'msg': "登录结果获取失败:${res.data['msg']}",
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
'status': false,
|
||||
'data': [],
|
||||
'msg': "TV版二维码申请失败:${authCodeRes['msg']}",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static Future qrcodePoll(authCode) async {
|
||||
var params = {
|
||||
'appkey': Constants.appKey,
|
||||
'auth_code': authCode.toString(),
|
||||
'local_id': '0',
|
||||
'ts': (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(),
|
||||
};
|
||||
String sign = Utils.appSign(
|
||||
params,
|
||||
Constants.appKey,
|
||||
Constants.appSec,
|
||||
);
|
||||
var res = await Request()
|
||||
.post(Api.qrcodePoll, queryParameters: {...params, 'sign': sign});
|
||||
if (res.data['code'] == 0) {
|
||||
String accessKey = res.data['data']['access_token'];
|
||||
Box localCache = GStorage.localCache;
|
||||
Box userInfoCache = GStorage.userInfo;
|
||||
var userInfo = userInfoCache.get('userInfoCache');
|
||||
localCache.put(
|
||||
LocalCacheKey.accessKey, {'mid': userInfo.mid, 'value': accessKey});
|
||||
return {
|
||||
'status': true,
|
||||
'data': [],
|
||||
'msg': '操作成功,当前获取的access_key为:$accessKey'
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
'status': false,
|
||||
'data': [],
|
||||
'msg': res.data['message'],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 获取up播放数、点赞数
|
||||
static Future memberView({required int mid}) async {
|
||||
var res = await Request().get(Api.getMemberViewApi, data: {'mid': mid});
|
||||
|
||||
@@ -325,7 +325,7 @@ class VideoHttp {
|
||||
String? accessKey = GStorage.localCache
|
||||
.get(LocalCacheKey.accessKey, defaultValue: {})['value'];
|
||||
if (accessKey == null || accessKey == "") {
|
||||
return {'status': false, 'msg': "本操作使用app端接口,请前往【隐私设置】刷新access_key"};
|
||||
return {'status': false, 'msg': "请退出账号后重新登录"};
|
||||
}
|
||||
var res = await Request().post(
|
||||
Api.dislikeVideo,
|
||||
@@ -355,7 +355,7 @@ class VideoHttp {
|
||||
String? accessKey = GStorage.localCache
|
||||
.get(LocalCacheKey.accessKey, defaultValue: {})['value'];
|
||||
if (accessKey == null || accessKey == "") {
|
||||
return {'status': false, 'msg': "本操作使用app端接口,请前往【隐私设置】刷新access_key"};
|
||||
return {'status': false, 'msg': "请退出账号后重新登录"};
|
||||
}
|
||||
assert((reasonId != null) ^ (feedbackId != null));
|
||||
var res = await Request().get(Api.feedDislike, data: {
|
||||
@@ -386,7 +386,7 @@ class VideoHttp {
|
||||
String? accessKey = GStorage.localCache
|
||||
.get(LocalCacheKey.accessKey, defaultValue: {})['value'];
|
||||
if (accessKey == null || accessKey == "") {
|
||||
return {'status': false, 'msg': "本操作使用app端接口,请前往【隐私设置】刷新access_key"};
|
||||
return {'status': false, 'msg': "请退出账号后重新登录"};
|
||||
}
|
||||
// assert ((reasonId != null) ^ (feedbackId != null));
|
||||
var res = await Request().get(Api.feedDislikeCancel, data: {
|
||||
|
||||
Reference in New Issue
Block a user