본문 바로가기
행복바이러스 행복바이러스

Bubble.io OAuth 2.0 연동 방법|외부 API 인증 흐름과 오류 해결

읽는 시간 약 14분

Bubble.io에서 외부 서비스를 연결하다 보면 API Key 하나만 입력해서 끝나는 경우도 있지만, 사용자 계정에 접근해야 하는 서비스는 OAuth 2.0 인증을 사용하는 경우가 많습니다.

처음 OAuth를 접하면 Client ID, Client Secret, Redirect URI, Authorization Code, Access Token 같은 용어가 한꺼번에 등장해서 복잡하게 느껴집니다.

하지만 전체 과정을 나눠보면 생각보다 구조는 명확합니다.

이번 글에서는 Bubble.io에서 외부 서비스를 OAuth 2.0 방식으로 연결한다고 가정하고 인증 요청부터 Access Token을 받아 API를 호출하기까지의 흐름을 살펴보겠습니다.

OAuth 2.0은 왜 필요한가?

예를 들어 Bubble로 만든 서비스에서 사용자의 외부 계정 데이터를 가져와야 한다고 가정해보겠습니다.

가장 단순하게 생각하면 사용자의 아이디와 비밀번호를 Bubble 앱에서 받아 외부 서비스에 전달할 수도 있을 것 같습니다.

하지만 이런 방식으로 사용자의 비밀번호를 직접 다루는 것은 적절하지 않습니다.

OAuth 2.0에서는 사용자가 외부 서비스의 인증 화면에서 직접 권한을 승인하고, 애플리케이션은 승인된 범위에서 사용할 수 있는 토큰을 받아 API에 접근하는 구조를 사용할 수 있습니다.

개념적으로 보면 다음과 같습니다.

Bubble 앱
   ↓
외부 서비스 로그인·권한 승인
   ↓
Authorization Code
   ↓
Access Token 요청
   ↓
Access Token 발급
   ↓
외부 API 호출

이 흐름을 먼저 이해하면 OAuth 설정 화면에 나오는 여러 값을 이해하기 쉬워집니다.

Client ID와 Client Secret의 차이

OAuth 앱을 등록하면 보통 Client IDClient Secret을 발급받습니다.

Client ID는 어떤 애플리케이션이 인증을 요청하는지 식별하는 값입니다.

반면 Client Secret은 외부에 노출되지 않도록 보호해야 하는 중요한 인증정보입니다.

특히 Client Secret을 페이지의 텍스트 요소나 JavaScript처럼 사용자의 브라우저에서 확인할 수 있는 위치에 넣어서는 안 됩니다.

Bubble에서 외부 API를 연결할 때도 어떤 값이 클라이언트에 노출될 수 있는지 확인하는 습관이 필요합니다.

Redirect URI가 중요한 이유

OAuth 설정에서 자주 문제가 생기는 부분이 Redirect URI입니다.

사용자가 외부 서비스에서 로그인과 권한 승인을 완료하면 다시 애플리케이션으로 돌아와야 합니다.

이때 사용하는 주소가 Redirect URI입니다.

전체 흐름은 다음과 같습니다.

Bubble 앱에서 로그인 시작
        ↓
외부 서비스 인증 화면
        ↓
사용자가 권한 승인
        ↓
등록된 Redirect URI로 이동
        ↓
Authorization Code 전달

외부 서비스 개발자 콘솔에 등록한 Redirect URI와 실제 인증 요청에 사용하는 URI가 일치하지 않으면 인증이 실패할 수 있습니다.

따라서 OAuth 오류가 발생했을 때는 토큰보다 먼저 Redirect URI를 확인해야 하는 경우도 많습니다.

Authorization 요청은 어떤 구조일까?

서비스마다 실제 URL과 필요한 파라미터는 다르지만 개념적으로는 다음과 같은 형태입니다.

https://provider.example/authorize
?client_id=CLIENT_ID
&redirect_uri=REDIRECT_URI
&response_type=code
&scope=profile

사용자가 이 인증 페이지에서 권한을 승인하면 Redirect URI로 돌아오면서 Authorization Code를 전달받는 방식입니다.

예를 들어 개념적으로 다음처럼 보일 수 있습니다.

https://myapp.example/callback?code=ABC123

여기에서 ABC123이 다음 단계에서 사용할 Authorization Code에 해당합니다.

실제 파라미터와 인증 방식은 연결하려는 서비스의 OAuth 문서를 확인해야 합니다.

Authorization Code 자체가 Access Token은 아닙니다

OAuth를 처음 구성할 때 많이 헷갈리는 부분입니다.

Authorization Code를 받았다고 해서 바로 API를 호출할 수 있는 것은 아닙니다.

일반적인 Authorization Code 흐름에서는 이 Code를 다시 Token Endpoint에 전달해 Access Token을 요청합니다.

Authorization Code
       ↓
Token Endpoint
       ↓
Access Token

개념적인 요청은 다음과 같습니다.

POST /oauth/token

grant_type=authorization_code
code=ABC123
client_id=CLIENT_ID
client_secret=CLIENT_SECRET
redirect_uri=REDIRECT_URI

실제 서비스에서는 인증 헤더나 요청 본문 형식이 다를 수 있으므로 해당 제공자의 문서를 기준으로 설정해야 합니다.

Access Token을 받았다면 API를 호출합니다

토큰 발급에 성공했다면 해당 토큰을 이용해 허용된 API에 접근할 수 있습니다.

대표적으로 Bearer Token 방식을 사용하는 API라면 다음과 같은 구조가 될 수 있습니다.

GET /api/user

Authorization: Bearer ACCESS_TOKEN

전체 과정은 결국 다음 다섯 단계입니다.

① 사용자가 외부 로그인 선택

② 외부 서비스에서 권한 승인

③ Authorization Code 수신

④ Code를 Access Token으로 교환

⑤ Access Token으로 API 호출

OAuth 설정 중 문제가 발생했다면 현재 어느 단계까지 성공했는지부터 확인하는 것이 중요합니다.

Bubble에서는 어디에서 처리해야 할까?

앞의 8번 글에서 Client-side와 Server-side Workflow를 구분했습니다.

OAuth에서도 이 구분이 중요합니다.

특히 Client Secret처럼 공개되어서는 안 되는 값이 필요한 요청이라면 사용자의 브라우저에 노출될 수 있는 방식으로 처리하지 않도록 설계해야 합니다.

외부 API를 Bubble에서 연결한다면 API Connector 또는 Backend Workflow 등 현재 Bubble이 제공하는 기능과 연결하려는 서비스의 인증 방식을 확인합니다.

중요한 기준은 단순합니다.

Secret은 Secret답게 관리해야 합니다.

Client Secret이나 장기간 사용할 인증정보를 페이지 요소나 공개 JavaScript에 직접 넣는 구조는 피해야 합니다.

Access Token은 영원히 사용할 수 있을까?

그렇지 않은 경우가 많습니다.

OAuth 제공자에 따라 Access Token에는 유효기간이 있을 수 있습니다.

예를 들어 토큰이 만료되면 이전까지 정상적으로 작동하던 API 요청이 갑자기 인증 오류를 반환할 수 있습니다.

서비스에서 Refresh Token을 제공한다면 이를 이용해 새로운 Access Token을 발급받는 흐름이 필요할 수도 있습니다.

Access Token 만료
       ↓
Refresh Token 확인
       ↓
Token Endpoint 요청
       ↓
새 Access Token
       ↓
API 호출 재개

다만 모든 서비스가 동일한 방식으로 Refresh Token을 제공하는 것은 아니므로 반드시 연결하려는 API의 공식 문서를 확인해야 합니다.

오류 1. redirect_uri_mismatch

OAuth 연결에서 비교적 이해하기 쉬운 오류입니다.

외부 서비스에 등록해놓은 Redirect URI와 실제 인증 요청에서 전달한 URI가 일치하지 않을 때 발생할 수 있습니다.

예를 들어 등록한 주소는

https://example.com/callback

인데 요청에서는 다른 경로나 도메인을 사용하고 있다면 문제가 될 수 있습니다.

개발 환경과 실제 Live 환경의 URL이 다른 경우에도 확인이 필요합니다.

따라서 다음을 비교합니다.

외부 서비스에 등록한 URI

Bubble에서 실제 사용하는 URI

두 값이 제공자의 규칙에 맞는지 확인합니다.

오류 2. invalid_client

invalid_client 같은 오류가 발생한다면 Client ID 또는 Client Secret을 우선 확인합니다.

잘못 복사했거나 개발용과 운영용 인증정보를 혼동했을 수도 있습니다.

또한 제공자에 따라 Client 인증정보를 요청 본문이 아닌 Authorization Header로 전달하도록 요구할 수도 있습니다.

따라서 단순히 값이 맞는지만 확인하지 말고 서비스가 요구하는 Client 인증 방식까지 확인해야 합니다.

오류 3. invalid_grant

Authorization Code를 Access Token으로 교환하는 단계에서 invalid_grant가 발생할 수도 있습니다.

원인은 서비스마다 다르지만 다음과 같은 부분을 점검해볼 수 있습니다.

Authorization Code가 만료되지 않았는가?

이미 사용한 Code를 다시 사용하고 있지는 않은가?

Redirect URI가 인증 요청 때와 동일한가?

요청하는 grant_type이 올바른가?

OAuth 오류를 해결할 때는 오류 메시지만 보고 코드를 전부 다시 만드는 것보다 어느 단계의 요청에서 오류가 발생했는지 확인하는 것이 빠릅니다.

오류 4. Access Token은 받았는데 API가 401을 반환한다

토큰 발급에 성공했다고 모든 API를 호출할 수 있는 것은 아닙니다.

토큰이 만료됐거나 요청 헤더 형식이 잘못됐을 수도 있고 필요한 Scope가 승인되지 않았을 수도 있습니다.

예를 들어 프로필 읽기 권한만 승인받은 토큰으로 다른 범위의 API를 호출하려 한다면 문제가 생길 수 있습니다.

이때는 다음을 확인합니다.

Token 유효 여부 → Authorization Header → Scope → API Endpoint

하나씩 확인하는 편이 좋습니다.

Scope는 최소한으로 요청합니다

OAuth 설정을 하다 보면 나중에 필요할 것 같다는 이유로 모든 권한을 요청하고 싶어질 수 있습니다.

하지만 사용하지 않는 권한까지 요청하는 방식은 피하는 편이 좋습니다.

예를 들어 사용자 이름과 프로필 사진만 필요하다면 서비스에서 제공하는 범위 안에서 필요한 Scope를 선택합니다.

앱의 기능이 늘어나 추가 권한이 필요해졌다면 그때 다시 인증 흐름을 검토하는 것이 좋습니다.

실제 문제 해결은 단계별 로그가 중요합니다

OAuth 전체 과정을 한꺼번에 보면 어디에서 실패했는지 찾기가 어렵습니다.

그래서 다음처럼 나눠 확인합니다.

1. Authorization URL 정상?
        ↓
2. 로그인·동의 화면 정상?
        ↓
3. Redirect 성공?
        ↓
4. Code 수신?
        ↓
5. Token 요청 성공?
        ↓
6. Access Token 수신?
        ↓
7. API 요청 성공?

예를 들어 4번까지 성공했다면 로그인 화면이나 Redirect 자체를 계속 수정할 이유가 없습니다.

문제는 5번 이후에 있을 가능성이 높기 때문입니다.

이런 식으로 범위를 좁혀가면 OAuth처럼 단계가 많은 인증 과정도 훨씬 관리하기 쉬워집니다.

토큰을 로그에 그대로 남기지 않습니다

오류를 찾다 보면 모든 값을 print하거나 로그에 기록하고 싶어질 수 있습니다.

하지만 Access Token, Refresh Token, Client Secret 같은 값은 그대로 로그에 남기지 않는 것이 좋습니다.

특히 운영 환경의 오류 로그가 외부 서비스나 여러 관리자에게 공유된다면 인증정보가 노출될 가능성이 있습니다.

필요하다면 전체 토큰이 아닌 일부 정보만 확인하거나 민감정보를 마스킹하는 방식을 사용합니다.

마무리

Bubble.io에서 OAuth 2.0을 연결할 때 가장 중요한 것은 설정값을 무작정 바꿔보는 것이 아니라 인증 과정을 단계별로 이해하는 것입니다.

기본 흐름은 어렵지 않습니다.

Authorization 요청 → 사용자 승인 → Authorization Code → Access Token → API 호출

오류가 발생하면 현재 어느 단계까지 정상적으로 진행됐는지부터 확인하세요.

Redirect 단계에서 실패했다면 Redirect URI를 확인하고, Token 발급 단계에서 실패했다면 Client 인증과 Code를 확인하고, API 호출 단계에서 실패했다면 Access Token과 Scope를 확인하는 식입니다.

그리고 Client Secret이나 Access Token처럼 중요한 인증정보는 사용자에게 노출되지 않도록 관리하는 것이 OAuth 연동에서 가장 기본적인 보안 원칙 중 하나입니다.

youngji
함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.