Files
xh-medical-sign-web/clinical-web/scripts/login.cjs
T

107 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 登录并保存会话,供页面渲染验证脚本复用。
*
* 为什么不 stub 接口:MEDISIGN 后端对无效 token 返回 401,
* utils/request.ts 的响应拦截器收到 401 会 clearAuthStorage() + 跳登录页,
* 伪造会话很容易被踢出去。走真实登录最省事。
*
* 验证码是强制的(不传会报「验证码错误或已过期」)。用法:
*
* node scripts/login.cjs # 第一步:抓验证码图片
* (用看图工具认出图片里的数字)
* node scripts/login.cjs 5274 # 第二步:带验证码登录,写 .session.json
*
* 结果写到 scripts/.session.json(已在 .gitignore 里,不会提交 token)。
*
* 文件用 .cjs 后缀:package.json 里的 "type": "module" 会把 .js 当 ES 模块,
* 而这里用 require 更简单,所以显式声明成 CommonJS。
*
* 依赖:Node 18+(内置 fetch)。无需额外安装依赖。
*/
const fs = require('fs')
const path = require('path')
const BASE_URL = process.env.VERIFY_BASE_URL || 'http://127.0.0.1:5173'
const USERNAME = process.env.VERIFY_USERNAME || 'admin'
const PASSWORD = process.env.VERIFY_PASSWORD || 'admin'
const OUT_DIR = __dirname
const CAPTCHA_JSON = path.join(OUT_DIR, '.captcha.json')
const CAPTCHA_PNG = path.join(OUT_DIR, '.captcha.png')
const SESSION_FILE = path.join(OUT_DIR, '.session.json')
async function fetchCaptcha() {
const res = await fetch(`${BASE_URL}/api/v1/auth/captcha`)
const json = await res.json()
if (json.code !== '0' && json.code !== 0) {
throw new Error('获取验证码失败: ' + json.message)
}
const { captchaId, imageBase64 } = json.data
fs.writeFileSync(CAPTCHA_JSON, JSON.stringify(json))
fs.writeFileSync(
CAPTCHA_PNG,
Buffer.from(String(imageBase64).replace(/^data:image\/\w+;base64,/, ''), 'base64'),
)
console.log('验证码已保存,请打开图片认出里面的数字:')
console.log(' ' + CAPTCHA_PNG)
console.log('captchaId = ' + captchaId)
console.log('')
console.log('然后执行: node scripts/login.cjs <识别出的数字>')
}
async function login(captchaCode) {
if (!fs.existsSync(CAPTCHA_JSON)) {
throw new Error('没有找到验证码,请先执行 node scripts/login.cjs 抓取验证码')
}
const { data } = JSON.parse(fs.readFileSync(CAPTCHA_JSON, 'utf8'))
const res = await fetch(`${BASE_URL}/api/v1/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
username: USERNAME,
password: PASSWORD,
captchaId: data.captchaId,
captchaCode,
}),
})
const json = await res.json()
if (json.code !== '0' && json.code !== 0) {
throw new Error(
'登录失败: ' + json.message + '(验证码可能已过期,重新执行 node scripts/login.cjs)',
)
}
fs.writeFileSync(SESSION_FILE, JSON.stringify(json.data, null, 2))
console.log('登录成功')
console.log(
' 用户 = ' + json.data.user.displayName + ' (' + json.data.user.username + ')',
)
console.log(' campusId = ' + json.data.user.campusId)
// 登录响应里 dataScope / permissions 可能缺失:权限以 /v1/authorization/me 为准。
console.log(' dataScope = ' + (json.data.user.dataScope ?? '(未返回)'))
console.log(' permissions = ' + (json.data.user.permissions?.length ?? 0) + ' 项')
console.log(' 会话已写入 ' + SESSION_FILE)
}
async function main() {
const captchaCode = process.argv[2]
if (captchaCode) {
await login(captchaCode.trim())
} else {
await fetchCaptcha()
}
}
main().catch((err) => {
console.error(err.message)
process.exit(1)
})