ceajs / cea

高校统一身份验证开发框架(已集成 CPDAILY 签到&查寝插件)
MIT License
90 stars 16 forks source link

FZU 登录流程 "应用没有权限" 错误 #18

Open luckycat0426 opened 2 years ago

luckycat0426 commented 2 years ago

.....某些学校的边缘情况可能更加复杂,这几天我校好像更新了今日校园鉴权流程 image

不直接请求 今日校园的验证服务,

http://id.***.edu.cn/authserver/login?service=https%3A%2F%2F***.campusphere.net%2Fiap%2FloginSuccess%3FsessionToken%3D8cf1a0a7e01541f384d728d588329239"

也可能是手机端流程原本就不一样,不知道cea是基于什么登陆流程实现的?

luckycat0426 commented 2 years ago

image post 主体也有所不同

luckycat0426 commented 2 years ago
// 登录前校验
function checkForm() {
    var cllt = $("#cllt").val();
    if(cllt=='userNameLogin'){
        if(utils.requireInput($(LOGIN_USERNAME_ID),0,100,$("#showErrorTip"),inputUserNameTip,$(LOGIN_USERNAME_ID).parent())
            || utils.requireInput($(LOGIN_PASSWORD_ID),0,32,$("#showErrorTip"),inputPasswordTip,$(LOGIN_PASSWORD_ID).parent())){
            return;
        }
        if (needCaptcha && captchaSwitch == "1" && utils.requireInput($(LOGIN_CAPTCHA_ID),0,10,$("#showErrorTip"),inputCodeTip,$(LOGIN_CAPTCHA_ID).parent())) {
            return;
        }
        $("#saltPassword").val(encryptPassword($(LOGIN_PASSWORD_ID).val(),$("#pwdEncryptSalt").val()));
        $(LOGIN_PASSWORD_ID).attr("disabled","disabled");
    }else if(cllt=='dynamicLogin'){
        if(utils.requireInput($(LOGIN_ACCOUNT_ID),0,100,$("#showErrorTip"),inputMobileTip,$(LOGIN_ACCOUNT_ID).parent())
            || utils.requireInput($(LOGIN_DYNAMIC_ID),0,100,$("#showErrorTip"),inputDynamicTip,$(LOGIN_DYNAMIC_ID).parent())){
            return;
        }
    }
    return true;
}

加密函数

function encryptAES(data, aesKey) {
    if (!aesKey) {
        return data;
    }
    var encrypted = getAesString(randomString(64) + data, aesKey, randomString(16));
    return encrypted;
}
function encryptPassword(pwd0, key) {
    try {
        return encryptAES(pwd0, key);
    } catch (e) {}
    return pwd0;
}

密钥

$("#pwdEncryptSalt").val()
'RADJfz0oeCxzjnPI'
beetcb commented 2 years ago

cea 用的是 PC 网页端的 userNamePasswordLogin(依稀记得是叫这个) 方法 Post 主体看起来没有大变化,应该(乐观情况下)是改变 edge-case.ts 里面的 formIdx 就可以了

luckycat0426 commented 2 years ago

根据网页抓的post请求构造了 image post body ,最后返回结果是200,不是302重定向, image

明天再看看往手机抓到的网址发包返回结果如何 遇到困难睡大觉:)

beetcb commented 2 years ago

YES! 睡觉

vic2ray commented 2 years ago

image post 主体也有所不同

刚好今天用golang写了下我们学校(NOTCLOUD)的模拟登录,看到你的这个错误(Status code 200, not 302)大概知道哪里漏了。我的登录流程如下:

  1. 请求金智教育portal首页:https://fzu.campusphere.net/portal/index.html

  2. 点击登录:https://fzu.campusphere.net/portal/login.html

  3. 以上请求会跳转到统一登录页面:http://id.fzu.edu.cn/authserver/login?service=https://fzu.campusphere.net/iap/loginSuccess?sessionToken=c6a12e5bf82b49f0afdb4ce8a1eb56d5

  4. 这个页面应该是全国统一的,post参数和加密固定,经测试有三个请求头必不可少

    • "Content-Type", "application/x-www-form-urlencoded"
    • "Referer", "我自己"
    • "Cookie", "route=跳转过来时Set-Cookie; JSESSIONID=跳转过来时Set-Cookie"
  5. 所以重点是获取到route和JSESSIONID,再post表单,否则就是响应200,就算密码对了也是登录错误

以上。因为破学校前两天登录页又抽风,导致cea自动登录时返回Unauthorized

之前的登录地址是:http://id.fzu.edu.cn/authserver/login?service=https://fzu.campusphere.net/portal/login

也就是不需要从portal页面点登录携带sessionToken跳转到统一登录页,但现在直接登录返回:

image

不知道其他学校是否存在一样的情况

vic2ray commented 2 years ago

cea 用的是 PC 网页端的 userNamePasswordLogin(依稀记得是叫这个) 方法 Post 主体看起来没有大变化,应该(乐观情况下)是改变 edge-case.ts 里面的 formIdx 就可以了

顺便提一下,看到edge-case.ts里面有福州大学,现在验证码的路径已经变了:

http://id.fzu.edu.cn/authserver/**checkNeedCaptcha.htl**?username=xxx&_=1636638646618

这几天登不上很郁闷呐

beetcb commented 2 years ago

https://github.com/ceajs/cea/blob/1c1b1891d1865a4834632aa3fed4992118736466/core/src/compatibility/edge-case.ts#L23-L31

哈哈,看起来变回默认的情形了

beetcb commented 2 years ago

为什么它们的更新感觉回滚到之前的老版本了 😂

beetcb commented 2 years ago

后期考虑把这个边缘情形维护成一个 API (在加载学校配置时抓取),这样方便改动,Cea 也不用以发布新版本的方式来更新了,这样可以缩短更新周期 @Juaran

luckycat0426 commented 2 years ago

image @Juaran 我这里清除掉route信息后再登陆,获得的响应是302,重新跳转到登陆界面,而不是200

vic2ray commented 2 years ago

image @Juaran 我这里清除掉route信息后再登陆,获得的响应是302,重新跳转到登陆界面,而不是200

注意这里Location后缀是except.message=Error...跳转链接已经坏掉了

luckycat0426 commented 2 years ago

现在遇到一个问题,在cea中发送POST请求到

https://fzu.campusphere.net/iap/loginSuccess?sessionToken=73de651dba294f7981f5ca99eb528290

不管账号密码是否正确,永远返回200,检查body为登录界面 用POSTMAN 发包,如果密码错误,将会返回401 状态码.

image

luckycat0426 commented 2 years ago

检查了一下,是header里面的cookie 中的JSESSIONID与请求url对不上的原因,不管请求什么,都会返回200

beetcb commented 2 years ago

上面提到的 Error decoding flow execution响应码卡在200 问题在这个项目的前身 https://github.com/beetcb/cea 就遇到过,是解决了的。

我不觉得当前 Cea 在 https://github.com/ceajs/cea/blob/main/core/src/crawler/login.ts 文件内的 NOTCLOUD 学校登陆逻辑有问题。

十分感谢你们付出时间 DEBUG 并分享到这里

但是我还是没看出错误的地方,方便的话,能给个测试账号吗,邮箱 i@beetcb.com

beetcb commented 2 years ago

或者说一下完整的登录流程和 Cookie 的特点,也行

beetcb commented 2 years ago

后期考虑把这个边缘情形维护成一个 API (在加载学校配置时抓取),这样方便改动,Cea 也不用以发布新版本的方式来更新了,这样可以缩短更新周期 @Juaran

已实现,准备检查一下你们学校适配性后发布新版本,可以参考 https://github.com/ceajs/cea/issues/20 提交适配

luckycat0426 commented 2 years ago

刚刚看到,我等下回去发个账号

luckycat0426 commented 2 years ago

.....URLSearchParams 这个对象是不是限制了长度,发现execution被截断了.

luckycat0426 commented 2 years ago

.....把截断的补全就正常302跳转了,应该是以前的exection 太短了,没有遇到url 字符限制.

beetcb commented 2 years ago

好,明天再研究研究 @luckycat0426

luckycat0426 commented 2 years ago

那个form index字段是为了定位general login 位置吧,为何不做成循环不同form表单,直到定位到general login为止,这样能少一个边缘情况,是因为出现了不兼容的情况吗?

beetcb commented 2 years ago

因为四种登录方式都有 general login,并且不同学校这个正确的表单中没有统一的可以区别其它几种登录方式的字段 @luckycat0426 你可以看看这个结构,尝试检索一下 generalLogin<form 两个关键字

https://transfer.sh/HQQ1EQ/i.html

beetcb commented 2 years ago

.....把截断的补全就正常302跳转了,应该是以前的exection 太短了,没有遇到url 字符限制.

这个限制应该只存在于把它真正用于 URL 请求时,Cea 是把字符放在 body 中请求的,没有限制

URLSearchParams 类并不会截断,node 源码中也没有相关证据,我写了一个小 demo,1000000 长度字符串也是通过测试了的:

async function urlParamsLimit(len) {
  const origalStr = 'a'.repeat(len)
  const string = new URLSearchParams({ a: origalStr }).toString()
  const urlStr = string.split('a=')?.[1]
  if (urlStr) {
    assertEq(origalStr, urlStr)
  }
}

function assertEq(arg1, arg2) {
  if (arg1 === arg2) {
    console.log(`Test Passed!`)
  } else {
    throw new Error(`Failed with ${arg1} = ${arg2}`)
  }
}

urlParamsLimit(1000000)

@luckycat0426

luckycat0426 commented 2 years ago

更新到最新的cea库好像用vscode 调试不了, 使用配置好的vscode 调试 提示 image

通过 vscode Javascript debug terminal 使用

node internal/lib/src/cli.js sign

调试 调用的是internal/node_modules/cea-core/lib/src/crawler/login.js node modules 下载的cea core 而不是工作区文件夹下的cea core

luckycat0426 commented 2 years ago

截断问题没再复现了......可能是我哪里配置出错了.

beetcb commented 2 years ago

fzu 有个问题,我用浏览器登录想看下请求,你给的账号密码都是对的,登录后出现这个报错界面:

https://transfer.sh/2Qr57B/fzu.txt

@luckycat0426

luckycat0426 commented 2 years ago

txt乱码了,如果显示是

应用没有权限 您的身份验证尝试不受信任,并且未经当前工作站的授权。

手机抓包也出现了该返回页面,但是能正常完成今日校园登陆.

beetcb commented 2 years ago

确实是这样提示的,能登录的话,行吧,现在就是要把 cea 的处理给适配好

luckycat0426 commented 2 years ago

imageimage 手机网页登陆和今日校园登陆抓包有所不同,手机网页登陆的请求和电脑认证入口类似,这个请求网址应该是无法登录到今日校园

vic2ray commented 2 years ago

现在还不能登上吗 @luckycat0426

vic2ray commented 2 years ago

我刚调试了下login.js,发现还是formIdx的问题

虽然文件vercel/data/school-edge-cases.json里的NOTCLOUD学校formIdx=2(这是正确的登录方式)

a9c5fb082fe9e8f18f705d6000a9702

但调试运行时发现login.js引用的compatibility/edge-case.js内容依旧为2.2.1版本之前的那三个学校:

也就是说虽然版本更新后文件去除了福州大学的旧的登录方式,但是打包之后的node_modules里面的文件还是旧的

(缓存还是什么鬼原因不知道)

手动改了下idx=2就能登录了

@beetcb @luckycat0426

beetcb commented 2 years ago

因为我还在等你们确认再发布布新版本的😂 @Juaran

beetcb commented 2 years ago

忘记提醒 @luckycat0426 了,因为新版是远程加载学校边缘信息的,所以要调试时需要先编译好,再手动运行

node internal/lib/src/cli.js load

再用 vscode 断点调试

vic2ray commented 2 years ago

因为我还在等你们确认再发布布新版本的😂 @Juaran

没啥问题,赶快发布吧😄

luckycat0426 commented 2 years ago

image

const form = $('form[method=post]').get(schoolEdgeCases.formIdx);
        console.log(schoolEdgeCases.formIdx);

@Juaran @beetcb formindex我之前遇到截断的问题的时候就检查过,发现表单位置变换后,已经改成2测试过,之前询问能否自动匹配formindex也是于此相关,最后还是登陆不上去,所以推测是请求网址变动. 现在测试一下好像还是登陆不了

beetcb commented 2 years ago

嗯,我等下拿你的号试试

luckycat0426 commented 2 years ago

忘记提醒 @luckycat0426 了,因为新版是远程加载学校边缘信息的,所以要调试时需要先编译好,再手动运行

node internal/lib/src/cli.js load

再用 vscode 断点调试

image 调试还是调用的internal目录下node_modules的cea-core,无法调试到根目录的cea-core 进行login代码的debug.

beetcb commented 2 years ago

这种行为是符合预期的,因为 monorepo 的管理工具 lerna 会将那个文件夹软链接成 core/

beetcb commented 2 years ago

还有是在 ts 文件里打断点,你这个界面我感觉不太对,似乎是 js 文件里打的

luckycat0426 commented 2 years ago

是我lerna配置出问题了吗, image 是在ts文件打的断点,在js打断点是为了演示调试会进入node_modules文件. image internal ts文件打的断点是可以正常触发的,在cea-core处的断点不生效

vic2ray commented 2 years ago

image

const form = $('form[method=post]').get(schoolEdgeCases.formIdx);
        console.log(schoolEdgeCases.formIdx);

@Juaran @beetcb formindex我之前遇到截断的问题的时候就检查过,发现表单位置变换后,已经改成2测试过,之前询问能否自动匹配formindex也是于此相关,最后还是登陆不上去,所以推测是请求网址变动. 现在测试一下好像还是登陆不了

我在Linux系统下安装v2.2.1之后,直接修改:

/usr/lib/node_modules/cea/node_modules/cea-core/lib/src/compatibility/edge-case.js

执行签到成功:

image

本地调试也是修改node_modules下cea-core内edge-case.js,签到成功

你试一下 @luckycat0426

beetcb commented 2 years ago

我用你给的账号测试不能登录,Cea 的逻辑没错,跟用浏览器访问 https://fzu.campusphere.net/portal/login 的每一步行为都是一致的 @luckycat0426

问题是用最后 POST 账号密码阶段 fzu 返回的状态码是 200,并不会跳转到 campusphere 地址,所以也就拿不到今日校园 COOKIE,Cea 会根据返回码来确认登录结果的,所以会输出登陆失败

image

我感觉这无解啊,浏览器都登录不了,如果 @Juaran 同学能登陆,难道是你给的账号有问题?

luckycat0426 commented 2 years ago

@Juaran 你应该是研究生吧,登陆验证和本科生可能不一样.

luckycat0426 commented 2 years ago

@beetcb http://id.fzu.edu.cn/authserver/login?service=http%3A%2F%2Fid.fzu.edu.cn%2Fauthserver%2Fmobile%2Fcallback%3FappId%3D673223559 用这个网址试一下,这个是今日校园手机端抓包抓到的

beetcb commented 2 years ago

返回了 Mobile,重定向跳转了一次 http://id.fzu.edu.cn/authserver/mobile/default.html#mobile_token=*********************** ,接下来是什么步骤呢,今日校园是如何拿到 Cookie 的呢?

beetcb commented 2 years ago

我用我手机也试一下

vic2ray commented 2 years ago

我刚找小学弟shilexi试了下,他们学院登上去直接没有权限,肯定拿不到MOD_AUTH_CAS

image

@luckycat0426 你的是这样吗

luckycat0426 commented 2 years ago

返回了 Mobile,重定向跳转了一次 http://id.fzu.edu.cn/authserver/mobile/default.html#mobile_token=***********************,接下来是什么步骤呢,今日校园是如何拿到 Cookie 的呢?

http://id.fzu.edu.cn/authserver/login?service=http%3A%2F%2Fehall.fzu.edu.cn%2Fnewmobile%2Fclient%2FuserStoreAppList

访问这个网址的时候headers 带着今日校园认证信息,之前的包没有看到set cookies,应该js生成的.

luckycat0426 commented 2 years ago

@Juaran 也是这样