API 레퍼런스
SCH Web Portal REST API 전체 엔드포인트 명세 — 110+ 엔드포인트
기본 정보
| 항목 | 값 |
|---|---|
| Base URL (개발) | http://localhost:8000/api |
| Base URL (프로덕션) | https://sch.wonchan.net/api |
| 인증 방식 | HttpOnly 쿠키 (sch_session) |
| 응답 형식 | application/json |
| 요청 Content-Type | application/json |
| 세션 TTL | 7200초 (2시간) |
인증 방식
SCH Web Portal은 Authorization 헤더 대신 HttpOnly 쿠키 기반 세션을 사용합니다.
1. POST /api/auth/login/ → Set-Cookie: sch_session=<token>; HttpOnly; SameSite=Lax
2. 이후 모든 요청에 브라우저가 자동으로 sch_session 쿠키 포함
3. 세션 만료 D-30분 전 POST /api/auth/refresh/ 호출로 갱신쿠키 속성:
| 속성 | 값 | 설명 |
|---|---|---|
HttpOnly | true | JavaScript document.cookie 접근 불가 |
SameSite | Lax | CSRF 공격 방어 |
Max-Age | 7200 | 2시간 |
Path | / | 모든 경로에 포함 |
세션 쿠키는 발급 시점의 클라이언트 IP + User-Agent에 암호학적으로 바인딩됩니다. IP가 바뀌면 (예: 모바일 로밍, VPN 전환) 세션이 자동 무효화되어 재로그인이 필요합니다.
공통 에러 응답 형식
모든 에러는 동일한 JSON 구조를 따릅니다.
{
"error": "ERROR_CODE",
"message": "사람이 읽을 수 있는 에러 메시지"
}전역 에러 코드
| 에러 코드 | HTTP | 발생 조건 |
|---|---|---|
UNAUTHORIZED | 401 | sch_session 쿠키 없음, 만료, 또는 IP/UA 바인딩 불일치 |
INVALID_TOKEN | 401 | 쿠키 변조 또는 복호화 실패 |
SCH_UNAVAILABLE | 503 | SCH 서버 (st.sch.ac.kr) 연결 실패 또는 타임아웃 |
SCH_SESSION_EXPIRED | 401 | 포털 쿠키는 유효하지만 학교 서버 세션(JSESSIONID/ECD_KEY)이 끊김 — 현재 GET /api/main/info/가 반환. 프론트엔드가 이 코드를 받으면 로그아웃하고 재로그인을 유도 |
요청 오류 코드
| 에러 코드 | HTTP | 발생 조건 |
|---|---|---|
MISSING_FIELDS | 400 | 필수 Body 필드 누락 또는 빈 값 |
MISSING_PARAMS | 400 | 필수 쿼리 파라미터 누락 |
INVALID_CREDENTIALS | 401 | 학번 또는 비밀번호 오류 |
2FA_REQUIRED | 401 | 이중인증(2FA) 계정 — 현재 미지원 |
CAPTCHA_FAILED | 403 | 로그인 Turnstile 검증 실패 (토큰 없음·위조·만료) |
AUTH_FAILED | 500 | 기타 SCH 인증 오류 |
// UNAUTHORIZED 예시
{
"error": "UNAUTHORIZED",
"message": "세션이 만료되었거나 유효하지 않습니다."
}
// SCH_UNAVAILABLE 예시
{
"error": "SCH_UNAVAILABLE",
"message": "학교 서버와 연결할 수 없습니다. 잠시 후 다시 시도하세요."
}데이터 흐름 패턴
패턴 1 — 실시간 SCH 프록시
학적정보, 성적, 시간표 등 대부분의 데이터는 DB에 저장되지 않고 SCH 서버에서 실시간 조회합니다.
Client → Portal API → SCH 서버 → 응답 변환 → Client이 패턴의 API는 SCH 서버가 응답하는 한 항상 최신 데이터를 반환하며, SCH 서버 장애 시 SCH_UNAVAILABLE (503)을 반환합니다.
패턴 2 — DB 저장
즐겨찾기, 시간표 테마, 공지사항, 학사일정은 Portal DB에 저장됩니다.
Client → Portal API → Portal DB → Client이 데이터는 SCH 서버와 무관하게 조회할 수 있습니다.
패턴 3 — 2단계 리포트
OZ 리포트(증명서·고지서) URL 생성 패턴. 먼저 화면용 정보를 조회하고, 이어서 출력 URL을 받습니다.
1. GET /api/{resource}/info/ → 화면에 보여줄 정보 + 출력 가능 여부
2. POST /api/{resource}/report/ → { url: "https://report.sch.ac.kr/..." }프론트엔드는 받은 URL을 window.open()으로 엽니다.
출력 파라미터를 클라이언트에서 받지 않습니다. 예전에는 1단계 응답의 report_params·notice·pass_data를 그대로 2단계 요청 본문에 실어 보냈는데, 그 안의 학번·prsnl_no가 실제 출력 대상을 결정하므로 로그인한 사용자가 타 학생의 증명서 URL을 발급받을 수 있었습니다(BOLA). 2026년 8월에 세션 학번으로 서버가 1단계 조회를 다시 태워 파라미터를 직접 만드는 방식으로 바꿨습니다.
그래서 2단계 요청은 본문이 비어 있거나, "무엇을 볼지"만 고르는 값(연도·학기 등)만 받습니다.
이 패턴을 사용하는 API: 해당학기 성적표, 등록 고지서, 기숙사비 고지서, 생활관 합격자 고지서, 장학 증명서, 교육비 납입 증명서, 각종 편람·현황 리포트
패턴 4 — 웹메일 SSO 중계
웹메일(mail.sch.ac.kr)만 인증 체계가 다릅니다. 종합정보시스템의 jsessionid/ecd_key로는 접근할 수 없어 SSO(sso.sch.ac.kr) RSA 로그인을 따로 태우고, 받은 메일 쿠키를 세션 페이로드에 넣어 다시 쿠키로 내려줍니다.
1. 첫 메일 요청 → 서버가 SSO 체인 수립 → Set-Cookie: sch_session(메일 쿠키 포함)
2. 이후 메일 요청 → 세션에서 메일 쿠키를 바로 읽어 mail.sch.ac.kr JSON API 중계이 패턴을 사용하는 API: /api/mail/* 전체. 자세한 내용은 웹메일 API를 참고하세요.
전체 엔드포인트 목록
| 그룹 | 엔드포인트 수 | 설명 |
|---|---|---|
| 인증 | 5 | 로그인, 갱신, 로그아웃, 세션 조회, Turnstile 설정 |
| 학적 | 8 | 학적정보, 메인통합조회, 학적사항 10탭, 공지사항, 학사일정, 즐겨찾기 |
| 성적 | 7 | 누적성적, 학기성적, 성적표, 졸업진도 |
| 시간표 | 20 | 테마 스토어, 교수/강의실별, 수강과목, 교과과정, 강의평가결과 |
| 장학 | 6 | 장학금 검색, 게시판, 증명서 |
| 기숙사 | 12 | 고지서, 호실, 통행증, 외박, 상벌점, 점호 마일리지 |
| 활동 | 15 | 봉사활동, 비교과과정, 봉사학습 |
| 등록금 | 5 | 등록금, 등록 고지서, 교육비 납입 증명서 |
| 웹메일 | 12 | 메일함 목록, 본문, 첨부, 작성·발송, 수신확인, 별표, 휴지통 |
| 기타 | 25+ | 강의평가, 교육만족도, 콰르텟, 하이플렉스, 국제학생증, SRC 프로그램실 등 |
인증 API
로그인, 세션 갱신, 로그아웃, 사용자 정보 조회
학적 API
학적정보, 메인통합조회, 학적사항 10탭, 공지사항, 학사일정, 즐겨찾기
성적 API
누적성적, 학기성적, 성적표(가정통신문), 졸업진도 상세
시간표 API
테마 스토어 CRUD, 교수/강의실별 조회, 수강과목, 교과과정
장학 API
조건별 장학금 검색, 모집 게시판, 장학 증명서 발급
기숙사 API
기숙사비 고지서, 호실배정, 통행증, 외박신청/취소, 상벌점, 점호 마일리지
활동 API
봉사활동 신청/취소, 비교과과정, 봉사학습 신청/취소/평가
등록금 API
등록금 납부 내역, 등록 고지서, 교육비 납입 증명서
웹메일 API
메일함 목록, 본문·첨부, 작성·발송, 수신확인, 별표, 휴지통
기타 API
강의평가 제출, 교육만족도, 콰르텟 티칭, 하이플렉스, 국제학생증, SRC 프로그램실
학기 코드 일람
모든 API에서 공통으로 사용하는 smt (학기 코드) 값입니다.
| 코드 | 학기 | 사용 범위 |
|---|---|---|
11 | 1학기 (3월~8월) | 성적, 학적, 시간표, 봉사 등 전체 |
21 | 2학기 (9월~2월) | 성적, 학적, 시간표, 봉사 등 전체 |
12 | 하계방학 | 기숙사 고지서 전용 |
22 | 동계방학 | 기숙사 고지서 전용 |
_current_semester() 서버 함수는 오늘 날짜로 (yy, smt)를 자동 반환합니다 (38월 → 12월 → 11, 921, 1~2월 → 전년도 21).