인증 API
로그인, 세션 갱신, 로그아웃, 사용자 정보 조회
개요
SCH Web Portal의 인증은 HttpOnly 쿠키 기반 세션 방식을 사용합니다.
로그인 성공 시 SCH 서버로부터 획득한 jsessionid, ecd_key 등을 AES-256-GCM으로 암호화한 토큰을 sch_session 쿠키로 발급합니다.
Authorization 헤더가 없습니다. 모든 인증은 sch_session 쿠키를 통해 이루어지며, 브라우저가 자동으로 쿠키를 포함합니다.
엔드포인트 목록
| 메서드 | 경로 | 인증 필요 | 설명 |
|---|---|---|---|
POST | /api/auth/login/ | 아니오 | SCH 로그인 + 세션 쿠키 발급 |
POST | /api/auth/refresh/ | 쿠키 | 세션 만료시간 연장 |
POST | /api/auth/logout/ | 아니오 | 쿠키 삭제 |
GET | /api/auth/me/ | 쿠키 | 세션 복원용 사용자 정보 |
POST /api/auth/login/
SCH 통합정보시스템에 인증하고, 세션을 암호화하여 HttpOnly 쿠키로 발급합니다.
요청
Body (application/json)
{
"std_no": "20201234",
"password": "your_password"
}| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
std_no | string | O | 학번 (공백 자동 제거) |
password | string | O | 비밀번호 |
응답
200 OK
{
"user": {
"std_no": "20201234",
"name": "홍길동"
},
"expires_at_ms": 1700007200000
}동시에 아래 쿠키가 설정됩니다:
Set-Cookie: sch_session=<token>; Path=/; HttpOnly; SameSite=Lax; Max-Age=7200| 응답 필드 | 타입 | 설명 |
|---|---|---|
user.std_no | string | 학번 |
user.name | string | 한국어 이름 |
expires_at_ms | number | 세션 만료 시각 (Unix milliseconds) |
세션 TTL은 **7200초 (2시간)**이며, 쿠키는 HttpOnly이므로 JavaScript에서 읽을 수 없습니다.
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
MISSING_FIELDS | 400 | std_no 또는 password 누락 혹은 빈 값 |
INVALID_CREDENTIALS | 401 | 학번 또는 비밀번호 오류 |
2FA_REQUIRED | 401 | 이중인증(2FA) 계정 — 현재 미지원 |
AUTH_FAILED | 500 | 기타 SCH 인증 오류 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |
// 예: 학번/비밀번호 오류
{
"error": "INVALID_CREDENTIALS",
"message": "학번 또는 비밀번호가 올바르지 않습니다."
}POST /api/auth/refresh/
현재 세션을 갱신하여 만료 시간을 현재 시각 기준 +2시간으로 연장합니다.
요청
Body 없음. 쿠키 sch_session이 포함되어야 합니다.
응답
200 OK
{
"expires_at_ms": 1700014400000
}갱신된 토큰으로 sch_session 쿠키가 덮어씌워집니다.
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
INVALID_TOKEN | 401 | 쿠키 없음, 만료, 또는 복호화 실패 |
세션 쿠키는 발급 시점의 클라이언트 IP와 User-Agent에 바인딩됩니다. 다른 IP나 브라우저에서 재사용하면 복호화가 실패하여 INVALID_TOKEN이 반환됩니다.
POST /api/auth/logout/
sch_session 쿠키를 만료 처리합니다.
요청
Body 없음.
응답
200 OK
{
"ok": true
}Set-Cookie: sch_session=; Path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT쿠키가 없어도 200을 반환합니다. SCH 서버에 별도로 로그아웃 요청을 보내지 않습니다.
GET /api/auth/me/
현재 로그인된 사용자 정보와 세션 만료 시간을 반환합니다.
페이지 재방문 시 로컬 상태를 복원할 때 사용합니다.
요청
쿠키 sch_session 포함.
응답
200 OK
{
"std_no": "20201234",
"name": "홍길동",
"expires_at_ms": 1700007200000
}| 필드 | 타입 | 설명 |
|---|---|---|
std_no | string | 학번 |
name | string | 이름 |
expires_at_ms | number | 세션 만료 시각 (Unix ms) |
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 또는 만료 |
세션 토큰 내부 구조
[Binary Layout]
version(1 byte) || kid(1 byte) || nonce(12 bytes) || ciphertext+GCM_tag(N+16 bytes)
Base64URL 인코딩하여 쿠키에 저장암호화 방식: AES-256-GCM
키 파생: HKDF-SHA256 (salt="sch-portal-v1", info="session-v1")
AAD (Additional Authenticated Data): HMAC-SHA256("ctx-binding", ip + "|" + user_agent)
AAD에 IP와 User-Agent가 바인딩되어 있어, 다른 환경에서 토큰을 재사용하면 GCM 인증이 실패합니다.
세션 페이로드 구조:
{
"std_no": "20201234", # 학번
"user_no": "U000001234", # SCH 사용자 번호
"name": "홍길동", # 이름
"jsessionid": "ABC123...", # SCH 서버 세션 ID
"ecd_key": "ENCKEY...", # SCH 서버 암호화 키
"dept_cd": "CS", # 학과 코드
"use_div": "", # 재학구분 (항상 빈 문자열)
"aug_div": "", # 인증구분 (항상 빈 문자열)
"expired": 1700007200 # 만료 Unix timestamp
}이 페이로드는 절대 클라이언트에 노출되지 않으며, 서버에서만 복호화합니다.