feat(lr): 懒人听书平台接入——App 通道搜索、web 章节列表、账密登录取流
This commit is contained in:
1 parent
83d3eb3b49
commit
6fb866e343
6 files changed
+243
No files matched your search
@@ -0,0 +1,51 @@
|
||||
// 懒人听书登录(web 通道 m.lrts.me/ajax/logon)
|
||||
// 参考社区下载器(yoval/lrts 等):POST form {account, pwd: base64(password)},
|
||||
// 成功响应 json.phone 非空,Set-Cookie 种下会话;取流接口必须携带该会话
|
||||
// (免费章节匿名也返回"收费章节未购买",2026-10-02 实测)。
|
||||
import { httpFetch } from '../request.ts'
|
||||
import { getCredentials, setCredentials } from '../auth/store.ts'
|
||||
|
||||
const UA_MI = 'Mozilla/5.0 (Linux; U; Android 4.1.1; zh-cn; MI2 Build/JRO03L) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 XiaoMi/MiuiBrowser/1.0'
|
||||
const LOGON_URL = 'https://m.lrts.me/ajax/logon'
|
||||
|
||||
/** 账号密码登录(成功保存会话 Cookie) */
|
||||
export const login = async({ account, password }: { account: string, password: string }) => {
|
||||
const form = `account=${encodeURIComponent(account)}&pwd=${Buffer.from(String(password), 'utf8').toString('base64')}`
|
||||
const { statusCode, body, headers } = await httpFetch(LOGON_URL, {
|
||||
method: 'post',
|
||||
headers: {
|
||||
'User-Agent': UA_MI,
|
||||
Referer: 'https://m.lrts.me/',
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: form,
|
||||
timeout: 15000,
|
||||
}).promise as any
|
||||
const b = body ?? {}
|
||||
if (statusCode != 200 || !b.phone) {
|
||||
const err = new Error(b.msg || '登录失败(账号或密码错误)')
|
||||
;(err as any).status = 401
|
||||
throw err
|
||||
}
|
||||
const setCookies = (headers as any)?.['set-cookie'] ?? []
|
||||
const cookie = (Array.isArray(setCookies) ? setCookies : [setCookies])
|
||||
.map((c: string) => String(c).split(';')[0].trim())
|
||||
.filter(Boolean)
|
||||
.join('; ')
|
||||
if (!cookie) throw new Error('登录成功但未返回会话 Cookie')
|
||||
setCredentials('lr', { cookie, phone: String(b.phone) })
|
||||
return { logged: true, phone: String(b.phone) }
|
||||
}
|
||||
|
||||
/** 登录会话 Cookie(未登录返回空串) */
|
||||
export const getLrCookie = (): string => (getCredentials('lr') as any)?.cookie || ''
|
||||
|
||||
/** 登录状态 */
|
||||
export const status = () => {
|
||||
const cred = getCredentials('lr') as { cookie?: string, phone?: string, updatedAt?: string } | null
|
||||
return cred?.cookie
|
||||
? { logged: true, phone: cred.phone, updatedAt: cred.updatedAt }
|
||||
: { logged: false }
|
||||
}
|
||||
|
||||
export default { login, getLrCookie, status }
|
||||
Reference in new issue
Block a user