From 43318de79a49960a6947ce6baac4f3affe6aa01c Mon Sep 17 00:00:00 2001 From: orz12 Date: Tue, 13 Aug 2024 08:41:27 +0800 Subject: [PATCH] =?UTF-8?q?mod:=20=E5=AF=86=E7=A0=81=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E6=89=8B=E6=9C=BA=E9=AA=8C=E8=AF=81=E9=A3=8E=E6=8E=A7=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=EF=BC=88=E6=9C=AA=E5=AE=8C=E6=88=90=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/http/api.dart | 20 ++++++++++ lib/http/login.dart | 66 +++++++++++++++++++++++++++++++++ lib/pages/login/controller.dart | 44 ++++++++++++++++++++++ 3 files changed, 130 insertions(+) diff --git a/lib/http/api.dart b/lib/http/api.dart index 4e67c14bb..b01869f30 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -502,6 +502,26 @@ class Api { static const String loginByPwdApi = '${HttpString.passBaseUrl}/x/passport-login/oauth2/login'; + /// 密码登录时,提示“本次登录环境存在风险, 需使用手机号进行验证或绑定” + /// 根据https://ivan.hanloth.cn/archives/530/流程进行手机号验证 + /// tmp_code + static const String safeCenterGetInfo = + '${HttpString.passBaseUrl}/x/safecenter/user/info'; + + /// 验证绑定手机号前的人机验证 + static const String preCapture = + '${HttpString.passBaseUrl}/x/safecenter/captcha/pre'; + + /// 密码登录时风控发送手机验证码 + ///sms_type str loginTelCheck + /// tmp_code str 验证标记代码 来自数据处理中的解析出的参数tmp_token + /// gee_challenge str 极验id 申请人机验证时得到(data->gee_challenge) + /// gee_seccode str 极验key 人机验证后得到(result->geetest_seccode) + /// gee_validate str 极验result 人机验证后得到(result->geetest_validate) + /// recaptcha_token str 验证token 申请人机验证时得到(data->recaptcha_token) + static const String safeCenterSmsCode = + '${HttpString.passBaseUrl}/x/safecenter/common/sms/send'; + /// 密码加密密钥 /// disable_rcmd /// local_id diff --git a/lib/http/login.dart b/lib/http/login.dart index 316ce39a8..6266ba607 100644 --- a/lib/http/login.dart +++ b/lib/http/login.dart @@ -349,4 +349,70 @@ class LoginHttp { }; } } + + // 密码登录时风控验证手机 + static Future safeCenterGetInfo({ + required String tmpCode, + }) async { + var res = await Request().get(Api.safeCenterGetInfo, data: { + tmpCode: tmpCode, + }); + 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'] + }; + } + } + + // 风控验证手机前的验证码 + static Future preCapture() async { + var res = await Request().post(Api.preCapture); + 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'] + }; + } + } + + // 风控验证手机 + static Future safeCenterSmsCode({ + String? smsType, + required String tmpCode, + required String geeChallenge, + required String geeSeccode, + required String geeValidate, + required String recaptchaToken, + }) async { + var res = await Request().post(Api.safeCenterSmsCode, data: { + 'sms_type': smsType ?? 'loginTelCheck', + 'tmp_code': tmpCode, + 'gee_challenge': geeChallenge, + 'gee_seccode': geeSeccode, + 'gee_validate': geeValidate, + 'recaptcha_token': recaptchaToken, + }); + 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'] + }; + } + } } diff --git a/lib/pages/login/controller.dart b/lib/pages/login/controller.dart index d5742944b..6f6fdf673 100644 --- a/lib/pages/login/controller.dart +++ b/lib/pages/login/controller.dart @@ -301,6 +301,50 @@ class LoginPageController extends GetxController SmartDialog.showToast('登录异常,接口未返回数据:${res["msg"]}'); return; } + if (data['status'] == 2) { + SmartDialog.showToast(data['message']); + return; + //{"code":0,"message":"0","ttl":1,"data":{"status":2,"message":"本次登录环境存在风险, 需使用手机号进行验证或绑定","url":"https://passport.bilibili.com/h5-app/passport/risk/verify?tmp_token=9e785433940891dfa78f033fb7928181&request_id=e5a6d6480df04097870be56c6e60f7ef&source=risk","token_info":null,"cookie_info":null,"sso":null,"is_new":false,"is_tourist":false}} + //todo: 后续登录流程:https://ivan.hanloth.cn/archives/530/ + String Url = data['url']!; + Uri currentUri = Uri.parse(Url); + var safeCenterRes = await LoginHttp.safeCenterGetInfo( + tmpCode: currentUri.queryParameters['tmp_token']!); + if (!safeCenterRes['status']) { + SmartDialog.showToast("获取安全验证信息失败,请尝试其它登录方式\n" + "(${safeCenterRes['code']}) ${safeCenterRes['msg']}"); + return; + } + Map accountInfo = { + "telVerify": safeCenterRes['data']['account_info']!['tel_verify']!, + "hide_tel": safeCenterRes['data']['account_info']!["hide_tel"]!, + }; + SmartDialog.showNotify( + msg: "将给你的手机号:${accountInfo['hide_tel']}发送短信验证码", + notifyType: NotifyType.alert, + alignment: Alignment.topCenter); + + var preCaptureRes = await LoginHttp.preCapture(); + if (!preCaptureRes['status']) { + SmartDialog.showToast("获取验证码失败,请尝试其它登录方式\n" + "(${preCaptureRes['code']}) ${preCaptureRes['msg']}"); + return; + } + String geeGt = preCaptureRes['data']['gee_gt']!; + String geeChallenge = preCaptureRes['data']['gee_challenge']; + captchaData.token = preCaptureRes['data']['recaptcha_token']!; + + getCaptcha(geeGt, geeChallenge, () { + LoginHttp.safeCenterSmsCode( + tmpCode: currentUri.queryParameters['tmp_token']!, + geeChallenge: geeChallenge, + geeSeccode: captchaData.seccode!, + geeValidate: captchaData.validate!, + recaptchaToken: captchaData.token!); + }); + + return; + } if (data['token_info'] == null || data['cookie_info'] == null) { SmartDialog.showToast( '登录异常,接口未返回身份信息,可能是因为账号风控,请尝试其它登录方式。\n${res["msg"]},\n $data');