Skip to main content
OAuth 앱을 쓰면 구성원이 각자 API Key를 발급하지 않아도 사내 포털이 그 구성원의 노트를 대신 조회할 수 있어요. 구성원은 티로 로그인과 동의 화면을 한 번 거치고, 앱은 그 사용자가 가진 권한 안에서만 동작해요.

언제 OAuth 앱을 쓰나요?

OAuth 앱은 Authorization Code 방식만 지원하고 PKCE가 필수예요. 사용자 없이 토큰을 받는 client_credentials 방식은 제공하지 않으니, 서버 간 연동에는 API Key를 쓰세요.

1단계. OAuth 앱 등록하기

조직 Admin 또는 DeveloperTiro Platform에서 등록해요. OAuth 앱은 조직 범위에서만 등록할 수 있어요.
1

OAuth 앱 화면 열기

Tiro Platform 사이드 메뉴에서 조직의 [OAuth 앱] 메뉴를 열고 [OAuth 앱 등록] 버튼을 눌러요.
2

앱 정보 입력

앱 이름, 1개 이상 10개 이하의 Redirect URI, 사용자에게 요청할 권한 을 입력해요. 각 Redirect URI는 로컬 개발용 loopback HTTP를 제외하고 https:// 로 시작해야 하며, 사용자 정보나 # 뒤 프래그먼트를 포함할 수 없어요. 앱은 인증 요청마다 등록한 목록에서 하나의 redirect_uri 를 선택해요.
3

Client ID와 Client Secret 저장

등록 직후 화면에 Client IDClient Secret 이 표시돼요. Client Secret은 이때 한 번만 보여주고 다시 확인할 수 없어요. 서버 환경 변수처럼 안전한 곳에 바로 저장하세요.
Redirect URI는 기본적으로 https:// 를 사용해요. 로컬 개발에서만 http://localhost, http://127.0.0.1, http://[::1] 과 각 주소의 포트를 등록할 수 있어요. 로컬용 앱과 운영용 앱을 따로 등록하면 개발 주소가 운영 설정에 섞이지 않아요. 인가 요청의 redirect_uri 는 등록한 목록 중 하나와 정확히 같아야 해요. 포트, 쿼리 문자열, 경로의 마지막 / 를 포함한 전체 문자열을 비교해요.
[OAuth 앱] 메뉴는 워크스페이스 화면에도 보이지만, 조직 범위에서만 열려요. 메뉴가 보이지 않으면 도입 담당 매니저나 partners@theplato.io로 요청하면 앱을 발급해 드려요.
Client Secret은 등록 화면을 닫으면 다시 볼 수 없어요. 잃어버렸다면 OAuth 앱 목록에서 그 앱 행 오른쪽의 새로고침 아이콘을 눌러 새 값을 받으세요. 재발급하는 순간 이전 Secret은 쓸 수 없으니, 앱을 쓰는 서버의 설정을 바꿀 준비를 하고 진행하세요. 앱을 폐기하면 그 앱으로 맺은 사용자 연결도 함께 끊겨요.

요청할 수 있는 권한

OAuth 앱은 사용자가 위임할 수 있는 권한만 요청해요. 조직 관리용 권한(organization_member:*, workspace:*, session:write)은 위임할 수 없고 조직 API Key로만 쓸 수 있어요. 앱이 실제로 닿는 범위는 사용자가 동의한 권한과 그 사용자가 티로에서 가진 권한이 겹치는 부분이에요. 사용자가 볼 수 없는 워크스페이스나 노트는 권한을 동의받아도 조회할 수 없어요.

2단계. 사용자 동의 받기

앱에서 사용자를 티로 인증 페이지로 보내요. 먼저 영문 대소문자, 숫자, -, ., _, ~만 사용해 43~128자의 code_verifier 를 만들어요. 암호학적으로 안전한 32바이트 난수를 패딩 없는 Base64URL로 인코딩하면 43자의 code_verifier 를 만들 수 있어요. 그 문자열을 UTF-8 바이트로 SHA-256 해시한 뒤 패딩 없는 Base64URL로 인코딩한 값을 code_challenge 로 보내요. 16진수 문자열이나 해시 원본 바이트를 그대로 보내면 인가 요청에서 거절돼요.
사용자가 티로 계정으로 로그인하고 동의 화면에서 앱 이름과 요청 권한을 확인한 뒤 승인하면, Redirect URI로 codestate 가 돌아와요.

콜백에서 state를 검증하세요

토큰을 교환하기 전에 state 부터 확인해요. authorize 요청 때 만든 값을 사용자 세션에 저장해 두고, 콜백으로 돌아온 값과 같은지 비교한 뒤 저장한 값을 지워요. 값이 없거나 다르면 그 자리에서 요청을 중단해요. 이 검증을 건너뛰면 공격자가 시작한 인증 결과가 피해자 세션에 붙어, 피해자가 모르는 계정으로 연결되는 로그인 CSRF가 가능해요.
SSO를 쓰는 조직의 구성원은 동의 화면 전에 평소처럼 사내 IdP로 로그인해요. 동의 화면은 그 구성원의 티로 계정 기준으로 뜨고, 앱도 그 계정의 권한만 넘겨받아요.

3단계. 토큰 교환하기

검증을 마친 code 를 서버에서 액세스 토큰으로 바꿔요. 아래 예제는 콜백에서 받은 인증 코드와 2단계에서 만든 code_verifier 를 환경 변수로 읽어요. Client Secret은 서버에서만 다루고 브라우저나 앱 코드에 넣지 마세요. 인증 코드는 한 번만 쓸 수 있어서 두 번 보내면 invalid_grant 로 거절해요.
클라이언트 인증은 HTTP Basic과 본문 파라미터(client_id, client_secret) 둘 다 지원해요.
expires_in 은 초 단위 남은 시간이고 앱 설정에 따라 달라요. 값을 코드에 고정하지 말고 응답에 온 값을 그대로 쓰세요. 응답에 refresh_token 이 함께 오는 앱은 아래 갱신 절차를 따르고, 오지 않는 앱은 만료 전에 사용자를 다시 인증 페이지로 보내면 돼요.

4단계. API 호출하기

액세스 토큰은 API Key와 같은 방식으로 Authorization 헤더에 넣어요. 호출할 수 있는 엔드포인트와 응답 형식은 API 개요에 정리한 것과 같아요.
응답에 담기는 노트는 동의한 사용자가 앱에서 볼 수 있는 범위예요. 그 사용자의 계정 API Key로 호출했을 때와 같아요.

5단계. 토큰 갱신하기

토큰 교환 응답에 refresh_token 이 있으면, 사용자에게 다시 동의를 받지 않고 새 액세스 토큰을 받을 수 있어요.
  • refresh 토큰은 한 번만 쓸 수 있어요. 응답에 새 refresh 토큰이 오면 이전 값은 버리고 새 값을 저장하세요.
  • 이미 쓴 refresh 토큰을 다시 보내면 탈취로 판단해서 그 사용자 연결의 토큰을 전부 무효화해요. 이때는 사용자에게 다시 동의를 받아야 해요.
  • 오랫동안 갱신하지 않은 연결은 만료돼요. 갱신할 때마다 만료 시점이 뒤로 밀려서, 꾸준히 쓰는 연결은 끊기지 않아요.
  • 앱을 폐기했거나 사용자가 연결을 끊었으면 갱신은 거절돼요.
갱신 요청을 보낸 뒤 네트워크 문제로 응답을 받지 못했다면 같은 refresh 토큰을 다시 보내지 마세요. 서버에서는 이미 교체가 끝났을 수 있어요. 저장한 토큰을 지우고 사용자에게 재인증을 안내하는 편이 안전해요.

연결 끊기

사용자가 앱 사용을 그만두면 refresh 토큰을 폐기해 연결을 끊어요. 이미 발급한 액세스 토큰은 expires_in 이 지나면 자연히 만료돼요.

서버 메타데이터

엔드포인트와 지원 방식은 표준 메타데이터 문서에서 확인할 수 있어요.

자주 묻는 오류


관련 페이지: 인증, 조직 단위 연동, API 개요