superplace
Developers
가이드

앱 연결(OAuth 2.1)

Claude와 ChatGPT 커넥터가 쓰는 OAuth 2.1을 타사 앱도 그대로 쓸 수 있습니다. 앱을 미리 등록하지 않습니다.

한눈에 보기

항목값
issuerhttps://api.superplace.so/core
인가 서버 메타데이터https://api.superplace.so/.well-known/oauth-authorization-server/core
보호 자원 메타데이터https://api.superplace.so/.well-known/oauth-protected-resource/core/v1/mcp
authorization_endpointhttps://api.superplace.so/core/v1/oauth/authorize
token_endpointhttps://api.superplace.so/core/v1/oauth/token
인가 방식인가 코드 + PKCE(S256 필수)
클라이언트 인증없음(공개 클라이언트)
범위(scope)없음. 연결한 사람의 권한이 그대로 적용됩니다.
액세스 토큰15분
인가 코드2분

앱 신원: 클라이언트 메타데이터 문서

client_id는 앱이 호스팅하는 클라이언트 메타데이터 문서(CIMD)의 HTTPS 주소입니다. 주소에는 경로가 있어야 합니다.

JSONCode
{ "client_id": "https://app.example.com/oauth/client.json", "client_name": "예시 앱", "redirect_uris": ["https://app.example.com/oauth/callback"] }
  • 문서의 client_id는 문서 주소와 같아야 합니다.
  • redirect_uris는 한 개 이상이어야 합니다. 인가 요청의 redirect_uri가 이 목록에 있어야 합니다.
  • 127.0.0.1, [::1], localhost 주소는 포트가 달라도 같은 주소로 봅니다. 로컬 앱은 이 주소를 씁니다.
  • client_name은 동의 화면에 앱 도메인과 함께 표시됩니다.
  • 문서는 superplace 서버가 인가 요청 때 직접 가져옵니다. 바깥에서 닿는 HTTPS 주소여야 하고 3초 안에 응답해야 합니다. 받은 문서는 5분 동안 기억합니다. 로컬에서만 도는 CLI 앱도 문서 자체는 공개 주소에 올려 두어야 합니다.
  • 세 필드 외의 항목은 읽지 않습니다. 문서를 못 가져오거나 client_id·redirect_uris가 맞지 않으면 동의 화면이 열리지 않고 오류가 표시됩니다.

1. 인가 요청

앱이 사용자를 인가 주소로 보냅니다. code_verifier를 만들고 SHA-256 해시를 base64url로 바꾼 값이 code_challenge입니다.

Code
https://api.superplace.so/core/v1/oauth/authorize ?response_type=code &client_id=https%3A%2F%2Fapp.example.com%2Foauth%2Fclient.json &redirect_uri=https%3A%2F%2Fapp.example.com%2Foauth%2Fcallback &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM &code_challenge_method=S256 &state=abc123

사용자는 superplace 콘솔의 동의 화면에서 로그인하고 연결할 범위를 고릅니다. 매장 하나, 조직 전체, 또는 여러 마디를 고를 수 있습니다. 허용하면 redirect_uri로 돌아옵니다.

Code
https://app.example.com/oauth/callback?code=spac_…&state=abc123&iss=https%3A%2F%2Fapi.superplace.so%2Fcore

취소하면 error=access_denied가 붙어 돌아옵니다. iss 값이 issuer와 같은지 확인하세요.

2. 토큰 교환

인가 코드는 2분 안에 한 번만 바꿀 수 있습니다. 본문은 application/x-www-form-urlencoded입니다.

TerminalCode
curl -X POST https://api.superplace.so/core/v1/oauth/token \ -d grant_type=authorization_code \ -d code="spac_…" \ -d code_verifier="$VERIFIER" \ -d client_id="https://app.example.com/oauth/client.json" \ -d redirect_uri="https://app.example.com/oauth/callback"
JSONCode
{ "access_token": "…", "token_type": "Bearer", "expires_in": 900, "refresh_token": "…" }

client_id와 redirect_uri는 인가 요청 때와 같아야 합니다. 다르면 invalid_grant가 돌아옵니다. 토큰 엔드포인트의 오류는 표준 봉투가 아니라 OAuth 형식(error, error_description)입니다.

3. 갱신

액세스 토큰은 15분 뒤 만료됩니다. 리프레시 토큰으로 새 토큰을 받습니다.

TerminalCode
curl -X POST https://api.superplace.so/core/v1/oauth/token \ -d grant_type=refresh_token \ -d refresh_token="$REFRESH" \ -d client_id="https://app.example.com/oauth/client.json"
  • 리프레시 토큰은 갱신할 때마다 새 값으로 바뀝니다. 응답의 새 값을 저장하세요.
  • 리프레시 토큰은 그 연결을 만든 앱만 쓸 수 있습니다. client_id가 다르면 거절됩니다.
  • 리프레시 토큰은 30일 동안 유효하고, 쓸 때마다 30일이 다시 시작됩니다. 회전 응답을 받지 못했으면 60초 안에는 직전 토큰으로 다시 요청해 같은 새 토큰을 받습니다.

토큰으로 호출하기

받은 액세스 토큰은 일반 Bearer 토큰입니다. API에 그대로 붙입니다.

TerminalCode
curl https://api.superplace.so/space/v1/reservations \ -H "Authorization: Bearer $ACCESS_TOKEN"

호출할 수 있는 API는 API 범위와 API 레퍼런스에 있습니다.

연결 범위 확인

사용자가 어느 매장이나 조직을 골랐는지는 토큰을 받은 뒤 GET /core/v1/me로 확인합니다. 매장 연결이면 placeId, 조직 연결이면 orgId가 오고, caps가 그 사람의 권한 목록입니다. 조직 연결은 그 조직의 매장 전체에 닿습니다. 목록 응답의 행마다 placeId가 들어가고, 한 매장으로 좁히려면 각 연산의 filter 인자에 {"placeId":"…"}를 보냅니다.

권한과 기록

  • 토큰에는 연결한 사람의 권한이 그대로 담깁니다. 콘솔에서 할 수 없는 일은 앱도 할 수 없습니다.
  • 앱이 한 모든 일은 매장 활동 기록에 연결한 사람의 이름으로 남습니다.
  • 사용자가 매장에서 빠지면 연결이 끝납니다.

연결 해제

사용자는 콘솔의 내 계정 › 연결된 앱에서 앱을 선택해 연결을 해제합니다. 해제하면 리프레시 토큰이 함께 삭제됩니다.

Last modified on