CLASSAPI/login
scrapbox.ioからclass.admin.tus.ac.jpに接続し、log in処理を行うscript
Cookieなしでlogin画面まで突破する
2021-04-10 14:49:51 ゲストユーザーでログインする関数を作った
2021-03-27 06:28:20 お気に入りリンクの取得処理を削った
DOMが変わって、簡単に取得できなくなった
そもそも使っていない
dependencies
code:auth.js
import {postToCLASS} from '../CLASSでページ遷移するscript/scrapbox.js';
export async function login({userId, password}) {
let {comSunFacesVIEW} = await getAuthData();
const html = await postToCLASS('/up/faces/login/Com00505A.jsp', {
'form1:htmlUserId': userId,
'form1:htmlPassword': password,
'form1:login.x': 0,
'form1.login.y': 0,
'form1': 'form1',
'com.sun.faces.VIEW': comSunFacesVIEW,
});
const dom = new DOMParser().parseFromString(html, 'text/html');
comSunFacesVIEW = dom.getElementById('com.sun.faces.VIEW').value;
// お知らせの概要を取得する
const announceSummary = [];
{
const baseId = 'form1:Poa00201A:htmlParentTable';
const announceTable = dom.getElementById(baseId);
for (const index of range(announceTable.firstElementChild.children.length)) {
announceSummary.push({
title: dom.getElementById(${baseId}:${index}:htmlHeaderTbl:0:htmlHeaderCol)
.textContent.trim(),
count: parseInt(dom.getElementById(${baseId}:${index}:htmlDisplayOfAll:0:htmlCountCol21702)
.textContent.replace(/全(\d+)件/, '$1')),
hasHiddenAnnounces: dom
.getElementById(${baseId}:${index}:htmlDisplayOfAll:0:htmlCountCol21702)
.nextElementSibling !== null,
id: index,
});
}
}
return {html, comSunFacesVIEW, announceSummary};
}
code:auth.d.ts
type Announce = {
unread: boolean;
important: boolean;
title: string;
updated: Date;
page: {
title: string;
sender: string;
lines: string[];
files: string[];
};
};
type Summary = {
title: string;
count: number;
hasHiddenAnnounces: boolean;
id: number;
};
export function login(props: {userId: string; password: string;}): Promise<{
html: string;
comSunFacesVIEW: string;
announceSummary: Summary[];
}>
ゲストユーザーでログインする
code:auth.js
export async function loginAsGuest() {
let {comSunFacesVIEW} = await getAuthData();
const html = await postToCLASS('/up/faces/login/Com00505A.jsp', {
'form1:guest.x': 0,
'form1.guest.y': 0,
'form1': 'form1',
'com.sun.faces.VIEW': comSunFacesVIEW,
});
const dom = new DOMParser().parseFromString(html, 'text/html');
comSunFacesVIEW = dom.getElementById('com.sun.faces.VIEW').value;
return {html, comSunFacesVIEW};
}
認証用cookieと、loginに必要なform dataを取得する関数
code:auth.js
async function getAuthData() {
let comSunFacesVIEW = undefined;
let jSessionId = undefined;
while (!comSunFacesVIEW) {
const response = await fetchCLASS('/up/faces/login/Com00505A.jsp');
jSessionId = response
.responseHeaders.split('\r\n')
.find(text => text.startsWith('set-cookie:'))
?.slice?.('set-cookie: '.length)
const dom = new DOMParser().parseFromString(response.responseText, 'text/html');
comSunFacesVIEW = dom.getElementById('com.sun.faces.VIEW').value;
}
return {jSessionId, comSunFacesVIEW};
}
test code
2021-03-21 02:13:28 server メンテナンス中だ……テストできないや。
2021-03-21 07:35:45 テストした。何度もログインし直せるみたい。
code:js
(async () => {
const {login} = await import('/api/code/takker/CLASSAPI%2Flogin/auth.js');
// 試しに10回 cookie無しでlog inしてみる
for (let i = 0; i < 10; i++) {
console.log((await login({userId, password})).announceSummary);
}
})();
code:js
import('/api/code/takker/CLASSAPI%2Flogin/test1.js')
.then(({execute}) => execute(/*...*/));
code:test1.js
import {login} from './auth.js';
export async function execute(userId, password) {
console.log((await login({userId, password})).announceSummary);
}
ゲストモードでログインしてみる
code:js
(async () => {
const {loginAsGuest} = await import('/api/code/takker/CLASSAPI%2Flogin/auth.js');
// 試しに10回 cookie無しでlog inしてみる
for (let i = 0; i < 10; i++) {
console.log(await loginAsGuest());
}
})();