dodam dodam logo

B1ND Docs

OAuth 토큰 발급

도담 앱은 미니앱 WebView를 열 때 URL 쿼리 파라미터로 도담 access token을 전달해요. 미니앱은 이 토큰을 자신의 서버로 전달하고, 서버에서 도담 OAuth API를 호출해 OAuth 토큰을 발급받아요.

전체 흐름

plaintext
[도담 앱 (Native)]
│ WebView URL에 ?token={dodam_access_token} 포함
[미니앱 프론트엔드]
│ URL 파라미터에서 token 추출 → 자신의 서버로 전달
[미니앱 서버]
│ 1. GET /oauth/authorize (도담 access token으로 검증)
│ 2. POST /oauth/authorize/consent (도담 access token으로 code 발급)
│ 3. POST /oauth/token (code → OAuth access token)
[도담 API 호출]
Authorization: Bearer {oauth_access_token}

1단계 — 프론트엔드에서 토큰 수신

도담 앱이 WebView를 열 때 URL에 token 파라미터를 포함해요.

plaintext
https://your-mini-app.com/?token=eyJhbGci...

프론트엔드에서 이 값을 파싱해 자신의 서버로 전달해요.

ts
// 예시: URL 파라미터에서 토큰 추출
const params = new URLSearchParams(window.location.search);
const dodamToken = params.get("token");
// 미니앱 서버로 전달
await fetch("/api/auth/dodam", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: dodamToken }),
});

2단계 — 서버에서 인가 요청

미니앱 서버가 받은 도담 access token으로 /oauth/authorize를 호출해요. 클라이언트 정보와 요청 scope가 유효한지 검증할 수 있어요.

http
GET https://dodam.b1nd.com/oauth/authorize
?response_type=code
&client_id={clientId}
&redirect_uri={redirectUri}
&scope=meal:read%20profile:read
&state={random_state}
Authorization: Bearer {dodam_access_token}

이미 동의한 적 있는 유저라면 응답의 consented 필드가 true로 돌아와요.

3단계 — 서버에서 동의 처리 → Authorization Code 발급

http
POST https://dodam.b1nd.com/oauth/authorize/consent
Authorization: Bearer {dodam_access_token}
Content-Type: application/json
{
"clientId": "{clientId}",
"redirectUri": "{redirectUri}",
"scope": "meal:read profile:read",
"state": "{state}",
"approved": true
}

응답에서 redirectUri 필드를 파싱해 code 값을 추출해요.

json
{
"data": {
"redirectUri": "https://your-mini-app.com/callback?code=abc123&state=xyz"
}
}

4단계 — 서버에서 OAuth 토큰 발급

추출한 code로 OAuth access token을 교환해요.

http
POST https://dodam.b1nd.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code={code}
&redirect_uri={redirectUri}
&client_id={clientId}
&client_secret={clientSecret}

성공 응답:

json
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImRvZGFtLW9hdXRoLXYxIn0...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "drt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"scope": "meal:read profile:read"
}

이후 access_tokenrefresh_token을 서버에 저장해 사용해요.

5단계 — 도담 API 호출

발급받은 OAuth access token으로 도담 API를 호출해요.

http
GET https://dodam.b1nd.com/meal/...
Authorization: Bearer {oauth_access_token}

토큰 만료 시 갱신

access token 유효시간은 1시간이에요. 만료되면 refresh token으로 갱신해요.

http
POST https://dodam.b1nd.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token
&refresh_token={refresh_token}
&client_id={clientId}
&client_secret={clientSecret}

refresh token 유효시간은 30일이에요. refresh token까지 만료되면 2~4단계를 다시 진행해야 해요.

scope 목록

미니앱 등록 시 신청한 scope 범위 내에서만 사용할 수 있어요.

scope설명
profile:read기본 프로필 조회 (이름, 학번)
meal:read급식 정보 조회
outgoing:read외출/외박 정보 조회
outgoing:write외출/외박 신청/취소
nightstudy:read야간 자율학습 정보 조회
nightstudy:write야간 자율학습 신청/취소
wakeupsong:read기상송 정보 조회
wakeupsong:write기상송 신청

클라이언트 등록

미니앱을 처음 등록할 때 clientIdclientSecret을 발급받아요. clientSecret은 최초 응답에서만 확인 가능하므로 반드시 안전하게 보관해요.

http
POST https://dodam.b1nd.com/oauth/clients
Content-Type: application/json
{
"clientName": "내 미니앱",
"redirectUris": ["https://your-mini-app.com/callback"],
"scopes": ["meal:read", "profile:read"],
"websiteUrl": "https://your-mini-app.com"
}

응답:

json
{
"data": {
"clientId": "dodam_a1b2c3d4e5f6",
"clientSecret": "dcs_xxxxxxxxxxxx",
"clientName": "내 미니앱",
"redirectUris": ["https://your-mini-app.com/callback"],
"scopes": ["meal:read", "profile:read"]
}
}