OAuth 2.0 Developer Guide

DS-GO 계정으로 로그인

외부 웹 앱에서 DS-GO 계정의 기본 프로필과 이메일을 안전하게 사용할 수 있습니다. 표준 Authorization Code 흐름과 PKCE S256을 지원합니다.

Base URLhttps://dsgo.today
Grant typeauthorization_code
Access tokenBearer · 1시간
Discovery/.well-known/oauth-authorization-server
현재 제공 범위

profileemail scope를 제공합니다. access token은 1시간 후 만료되며 refresh token은 발급하지 않습니다.

빠른 시작

  1. 1
    내 앱에서 OAuth 앱을 등록합니다.

    앱 이름과 실제 callback 전체 주소를 입력하고 Client ID와 Client secret을 발급받습니다.

  2. 2
    사용자를 인가 엔드포인트로 보냅니다.

    예측 불가능한 state를 세션에 저장하고 필요한 scope를 함께 요청합니다.

  3. 3
    callback에서 code와 state를 확인합니다.

    돌아온 state가 세션에 저장한 값과 정확히 일치하는지 먼저 검증합니다.

  4. 4
    서버에서 code를 access token으로 교환합니다.

    Client secret은 브라우저에 노출하지 말고 서버에서만 사용합니다.

  5. 5
    Bearer token으로 사용자 정보를 조회합니다.

    sub를 외부 서비스에서 변하지 않는 DS-GO 사용자 식별자로 저장합니다.

Authorization Code

인증 흐름

브라우저 이동과 서버 간 요청을 분리하면 Client secret을 사용자에게 노출하지 않고 계정을 연결할 수 있습니다.

내 앱

state와 PKCE 준비세션마다 무작위 state를 만들고, PKCE 사용 시 verifier에서 S256 challenge를 생성합니다.

브라우저

GET /oauth/authorize사용자를 DS-GO 승인 화면으로 이동합니다.

DS-GO

callback으로 복귀승인되면 등록된 redirect_uri에 code와 기존 state를 전달합니다.

내 서버

POST /api/oauth/tokencode, redirect_uri, Client 인증 정보로 access token을 요청합니다.

내 서버

GET /api/oauth/userinfoBearer token으로 승인된 범위의 사용자 프로필을 조회합니다.

API Reference

API 레퍼런스

GET/oauth/authorize

사용자를 DS-GO 로그인 및 승인 화면으로 이동합니다.

파라미터필수설명
response_type필수code만 지원
client_id필수내 앱에서 발급한 Client ID
redirect_uri필수등록한 callback 전체 주소와 정확히 일치해야 함
scope선택profile email, 생략 시 profile
state필수CSRF 방지를 위한 최대 1,024자의 무작위 값
code_challenge선택PKCE S256 challenge
code_challenge_methodPKCES256만 지원
https://dsgo.today/oauth/authorize?
  response_type=code&
  client_id=CLIENT_ID&
  redirect_uri=https%3A%2F%2Fexample.com%2Fauth%2Fcallback&
  scope=profile%20email&
  state=RANDOM_STATE
POST/api/oauth/token

1회용 authorization code를 access token으로 교환합니다. Client 인증은 HTTP Basic을 권장하며 form body도 지원합니다.

curl -X POST https://dsgo.today/api/oauth/token \
  -u 'CLIENT_ID:CLIENT_SECRET' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode 'code=AUTHORIZATION_CODE' \
  --data-urlencode 'redirect_uri=https://example.com/auth/callback'
{
  "access_token": "dsga_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "profile email"
}
GET/api/oauth/userinfo

승인된 scope에 해당하는 현재 사용자 정보를 반환합니다.

curl https://dsgo.today/api/oauth/userinfo \
  -H 'Authorization: Bearer ACCESS_TOKEN'
{
  "sub": "USER_ID",
  "name": "사용자 이름",
  "preferred_username": "username",
  "email": "user@example.com",
  "email_verified": true
}
POST/api/oauth/revoke

발급한 access token을 폐기합니다. Client 인증과 form body의 token 값이 필요합니다.

Proof Key for Code Exchange

PKCE S256

인가 요청을 시작한 클라이언트만 code를 교환할 수 있도록 PKCE 사용을 권장합니다. DS-GO는 S256 방식만 지원합니다.

  1. 1
    code_verifier 생성

    [A-Z, a-z, 0-9, ., _, ~, -] 문자로 43~128자 무작위 값을 만듭니다.

  2. 2
    code_challenge 계산

    BASE64URL(SHA256(code_verifier))를 계산하고 padding은 제거합니다.

  3. 3
    인가 요청과 token 요청에 나눠 전달

    인가 요청에는 challenge와 S256, token 요청에는 원래 verifier를 보냅니다.

Client secret도 필요합니다

현재 DS-GO token endpoint는 PKCE 사용 여부와 관계없이 등록 시 발급한 Client 인증 정보를 요구합니다.

Errors & Limits

오류와 제한

오류의미
invalid_request필수 파라미터 또는 PKCE 형식이 올바르지 않음
invalid_clientClient ID 또는 Client secret 인증 실패
invalid_redirect_uri등록되지 않은 callback 주소
invalid_scope지원하지 않는 scope 요청
access_denied사용자가 앱의 접근 요청을 거절함
invalid_grantcode가 만료·사용되었거나 PKCE 검증 실패
invalid_tokenaccess token이 없거나 만료·폐기됨
  • 계정당 OAuth 앱은 최대 20개까지 등록할 수 있습니다.
  • 앱당 callback URL은 최대 10개까지 등록할 수 있습니다.
  • 운영 URL은 HTTPS만 허용하며 localhost, 127.0.0.1, ::1은 HTTP를 사용할 수 있습니다.
  • authorization code는 10분 동안 유효하며 한 번만 사용할 수 있습니다.
Security

보안 가이드

  • Client secret은 서버 전용 비밀로 보관하세요. 브라우저 코드, Git 저장소, 로그에 넣지 마세요.
  • 모든 요청에 state를 사용하세요. callback에서 세션 값과 상수 시간 비교로 검증하세요.
  • redirect_uri를 동적으로 조립하지 마세요. 등록한 고정 전체 주소를 그대로 사용하세요.
  • 사용자 연결 키는 sub를 사용하세요. 이름과 이메일은 변경될 수 있습니다.
  • 로그아웃이나 연결 해제 시 token을 폐기하세요. Client secret 유출이 의심되면 즉시 다시 발급하세요.