콘텐츠로 이동

인증과 로그인

스토어프론트 API 인증은 두 계층입니다.

계층필요 시점헤더
사이트 식별모든 스토어프론트 API 요청X-Runmoa-Site-Key
사용자 인증마이페이지, 로그인 장바구니, 주문, 게시글/댓글 작성 등Authorization: Bearer USER_LOGIN_TOKEN
GET /api/storefront/v1/auth/schoolmoa-client
X-Runmoa-Site-Key: moa_pub_xxxxxxxxx
Accept: application/json

응답의 scid 값을 Schoolmoa 로그인 URL의 client_id로 사용합니다.

{
"scid": "schoolmoa-client-id-for-this-site"
}
const { scid } = await fetch(`${API_BASE}/auth/schoolmoa-client`, {
credentials: 'include',
headers: {
'X-Runmoa-Site-Key': STOREFRONT_KEY,
Accept: 'application/json',
},
}).then((response) => response.json());
const redirectUri = `${window.location.origin}/auth/callback`;
const loginUrl = new URL('https://www.runmoa.com/login/');
loginUrl.searchParams.set('client_id', scid);
loginUrl.searchParams.set('redirect_uri', redirectUri);
window.location.href = loginUrl.toString();
POST /api/storefront/v1/auth/schoolmoa/callback
X-Runmoa-Site-Key: moa_pub_xxxxxxxxx
Content-Type: application/json
Accept: application/json
{
"code": "AUTHORIZATION_CODE"
}

성공 응답에는 사용자 토큰이 포함됩니다. user는 최소 정보만 포함될 수 있으므로, 화면에 프로필을 표시할 때는 토큰 저장 후 GET /me를 호출합니다.

{
"user": {
"ID": 123,
"name": "홍길동"
},
"token": "USER_LOGIN_TOKEN",
"token_type": "Bearer"
}
GET /api/storefront/v1/me
X-Runmoa-Site-Key: moa_pub_xxxxxxxxx
Authorization: Bearer USER_LOGIN_TOKEN
Accept: application/json

대표 /me 응답:

{
"user": {
"ID": 123,
"id": 123,
"name": "홍길동",
"nickname": "gildong",
"email": "buyer@example.com",
"phone": "01012345678",
"user_phone": "01012345678",
"timezone": "Asia/Seoul"
}
}

잘못된 callback code:

{
"message": "로그인에 실패하였습니다.",
"e": "authorization_code not found error"
}

사용자 토큰이 없거나 만료된 경우:

{
"message": "Unauthenticated."
}

스토어프론트 키가 현재 도메인에서 허용되지 않은 경우:

{
"message": "이 API 키는 현재 도메인에서 사용할 수 없습니다."
}

브라우저 앱은 401을 받으면 저장된 사용자 토큰을 제거하고 로그인 버튼을 보여줍니다. 403을 받으면 사이트 관리자에게 스토어프론트 키와 허용 도메인 설정을 확인하도록 안내합니다.

POST /api/storefront/v1/auth/logout
X-Runmoa-Site-Key: moa_pub_xxxxxxxxx
Authorization: Bearer USER_LOGIN_TOKEN
Accept: application/json

정적 프론트엔드에서는 토큰 저장 방식을 사이트 정책에 맞춰 정합니다. 구현이 단순해야 하면 localStorage를 쓸 수 있지만, XSS 위험을 줄이려면 프론트엔드 코드와 외부 스크립트 관리를 엄격히 해야 합니다.

서버가 있는 구조에서는 서버 세션 또는 httpOnly 쿠키로 토큰을 보관할 수 있습니다.