iOS 및 Android 개발에서의 Access Token — 핵심 개념, 토큰 유형 및 작동 방식

저자: IT Sectr 게시일: 2026-04-06 읽는 시간: 9 분

Access Token—클라이언트 애플리케이션이 보호된 API 리소스에 액세스하기 위해 서버에 제시하는 자격 증명입니다. 사용자 인증 후, 인증 서버는 access token을 발급하며, 클라이언트는 각 요청과 함께 HTTP 헤더 Authorization에 이 토큰을 전송합니다. OAuth.net, 2025에 따르면, access token은 opaque string(의미 없는 임의 문자열) 또는 JWT(내부에 데이터를 포함하는 자체 완결형 토큰)일 수 있으며, 형식 선택은 시스템의 아키텍처와 성능 요구 사항에 따라 달라집니다.

핵심 요점

  • Access Token—Authorization 헤더를 통해 전송되는 API용 임시 패스
  • Opaque token—서버가 인트로스펙션 엔드포인트를 통해 확인하는 임의 문자열
  • JWT 형식—서버 요청 없이 로컬에서 검증되는 자체 완결형 서명 토큰
  • 짧은 TTL—토큰 유출 시 피해를 최소화하기 위한 15~60분
  • Scope—access token에는 액세스 가능한 리소스를 결정하는 제한된 권한 집합이 포함됩니다

Access Token이란?

Access Token—클라이언트(모바일 앱, SPA, 서버)가 보호된 API 엔드포인트에 대한 HTTP 요청을 인증하는 데 사용하는 문자열입니다. 토큰은 사용자가 신원을 확인하고 애플리케이션에 적절한 권한(scope)을 부여한 후 인증 서버에서 발급됩니다.

Access token은 OAuth 2.0 프로토콜과 그 위에 구축된 모든 시스템(OpenID Connect, Firebase Authentication, Auth0, Keycloak)의 핵심 요소입니다. Access token이 없으면 보호된 API에 대한 요청이 처리되지 않습니다. 서버는 HTTP 401 Unauthorized를 반환합니다. 토큰은 사용자를 직접 식별하지 않습니다. 클라이언트가 사용자를 대신하여 특정 작업을 수행할 권리가 있음(권한 부여)을 확인할 뿐, 사용자가 누구인지(인증)는 확인하지 않습니다.

Okta, 2025에 따르면, 공개 API의 80% 이상이 Authorization 헤더에 access token을 포함한 Bearer 스키마를 사용하여 구식 인증 방식(Basic Auth 및 API Key)을 대체하고 있습니다. Access token은 위임된 권한 부여의 기초이기도 합니다. 이는 사용자가 애플리케이션에 다른 서비스의 데이터에 대한 제한된 액세스를 허용하는 모델입니다. 예를 들어, 사진 편집 모바일 앱이 OAuth 2.0을 통해 Google Drive에 대한 액세스를 요청하면, 사용자는 특정 scope가 나열된 동의 화면을 보고 확인 후 해당 권한이 있는 access token을 받습니다.

Access Token 작동 방식

메커니즘 access token은 Bearer 스키마를 기반으로 합니다. 클라이언트는 각 HTTP 요청에 Authorization: Bearer <token> 헤더를 추가합니다. 리소스 서버(API)는 토큰을 수신하고, 유효성을 검사하며, 액세스 가능한 리소스를 결정합니다. 검증은 두 가지 방식으로 이루어집니다. 로컬(JWT의 경우) 또는 인트로스펙션 엔드포인트를 통해(opaque 토큰의 경우)입니다.

Bearer Token 스키마

Bearer token은 토큰을 제시하는 사람(bearer)이 누구든 해당 액세스 권한을 얻음을 의미합니다. 이는 전송 및 저장 중 토큰 보호에 높은 요구 사항을 부과합니다. Bearer 스키마는 클라이언트가 토큰의 소유권을 암호학적으로 증명할 것을 요구하지 않습니다. 단지 전송하기만 하면 됩니다. 따라서 HTTPS는 필수입니다. 트래픽 암호화 없이는 공격자가 토큰을 가로채서 즉시 사용할 수 있습니다.

Cloudflare, 2025에 따르면, 안전하지 않은 HTTP 연결을 통한 Bearer token 가로채기는 요청 전송 후 평균 12초 이내에 발생합니다. HTTPS와 짧은 access token TTL(15~30분)을 사용하면 위험이 거의 0으로 줄어듭니다. 추가적인 애플리케이션 수준 보호로는 OAuth 2.0 Token Binding(RFC 8471)을 통한 요청 출처 확인이 있습니다. 클라이언트는 토큰에 바인딩된 TLS 키의 소유권을 증명하여 가로채기를 통한 토큰 도난을 무용지물로 만듭니다.

Access Token 유형

Access Token에는 opaque와 JWT(자체 완결형)의 두 가지 형식이 있습니다. 이들 간의 선택은 인증 시스템을 설계할 때 주요 아키텍처 결정 사항 중 하나입니다.

Opaque vs JWT

매개변수Opaque TokenJWT
형식임의 문자열(32~64바이트)서명이 포함된 Base64 인코딩 JSON
검증인트로스펙션 엔드포인트를 통해(HTTP 요청)로컬(암호학적 서명)
데이터 포함아니요—식별자만 포함예—토큰 내부에 클레임 포함
취소즉시—서버 측 확인블랙리스트 또는 짧은 TTL을 통해
성능각 요청→인트로스펙션(RTT)로컬 검증(RTT 없음)
크기~100바이트~500~2000바이트

Opaque token은 즉각적인 액세스 취소와 중앙 집중식 권한 확인이 필요한 시스템에 선호됩니다. JWT는 성능과 네트워크 호출 최소화가 중요한 마이크로서비스 아키텍처에 적합합니다. 많은 제공업체(Auth0, Keycloak)는 두 형식을 모두 지원하며 클라이언트별로 토큰 유형을 구성할 수 있습니다. Opaque와 JWT의 선택은 제어와 성능 간의 균형입니다. opaque는 서버에 완전한 제어권을 제공하고, JWT는 최소한의 지연 시간을 제공합니다.

Access Token 수명 주기

수명 주기 access token은 발급, 전송, 사용, 만료의 네 단계로 구성됩니다. 각 단계에는 고유한 보안 요구 사항과 프로토콜 제약이 있습니다.

만료 및 갱신

Access Token의 수명은 제한적이며 일반적으로 15~60분입니다. expires_in 값은 토큰 발급 시 인증 서버의 응답에 표시됩니다. 이 시간이 지나면 토큰은 유효하지 않게 되며 클라이언트는 refresh token 메커니즘을 통해 새 토큰을 받아야 합니다. 클라이언트는 두 가지 방법으로 만료를 확인할 수 있습니다. JWT의 exp 필드(로컬) 또는 HTTP 401 응답(opaque 토큰의 경우)을 통해 확인합니다.

Auth0 Best Practices, 2025에 따르면, 모바일 애플리케이션에 최적의 access token TTL은 15~30분입니다. TTL이 너무 짧으면(5분 미만) 갱신할 때마다 토큰 엔드포인트에 과도한 부하가 발생합니다. 10,000명의 사용자와 5분 TTL의 경우, 서버는 피크 시간에 분당 최대 2,000개의 갱신 요청을 받습니다. TTL이 너무 길면(2시간 이상) 토큰 유출 시 공격 창이 확대되어, 공격자가 액세스가 자동으로 차단되기까지 몇 시간 동안 손상된 토큰을 사용할 수 있습니다.

Access Token 보안

보안 access token의 보안은 모든 단계에서 보장되어야 합니다. 장치 저장 시, 네트워크 전송 시, 서버 처리 시 모두 포함됩니다. 기본 권장 사항은 다른 애플리케이션이나 프로세스에서 액세스할 수 있는 위치에 access token을 절대 저장하지 않는 것입니다.

저장 및 전송 중 보호

모바일 장치에서 access token은 다음과 같이 저장됩니다. iOS에서는 kSecAttrAccessibleAfterFirstUnlock 속성을 가진 Keychain(백그라운드 업데이트를 위해 장치가 잠겨 있어도 첫 번째 잠금 해제 후 토큰에 액세스 가능). Android에서는 EncryptedSharedPreferences에 저장됩니다. Access token은 NSUserDefaults, SharedPreferences, 외부 저장소의 파일 또는 애플리케이션 로그에 절대 저장되어서는 안 됩니다. 전송 중에는 TLS 1.3 또는 1.2를 사용한 HTTPS만 허용됩니다. 각 API 요청에 대해 access token은 Authorization: Bearer 헤더로 전송되어야 하며, URL 매개변수(쿼리 문자열)로 전송해서는 안 됩니다. URL은 서버 및 브라우저 로그에 기록됩니다.

OWASP Mobile Top 10, 2025에 따르면, 장치의 부적절한 토큰 저장(M1: Improper Platform Usage)과 안전하지 않은 데이터 전송(M3: Insecure Communication)은 계정 손상으로 이어지는 가장 흔한 모바일 취약점 상위 3개에 속합니다. 추가 조치로 access token이 포함된 모든 요청에 인증서 핀닝을 사용합니다. 클라이언트는 표준 CA 체인뿐만 아니라 사전 저장된 인증서 지문(SHA-256 fingerprint)을 통해서도 서버 인증서를 확인합니다. 이는 CA가 손상된 경우에도 중간자 공격을 방지합니다.

Kotlin 코드 예제

다음은 Android용 Kotlin의 예제로, Authorization 헤더에 access token을 포함한 요청 전송과 refresh token을 통한 자동 갱신으로 401을 처리하는 방법을 보여줍니다. 사용자 정의 Interceptor와 함께 OkHttp가 사용됩니다.

kotlin
data class TokenStore {
    fun getAccessToken(): String? {
        // Reading from EncryptedSharedPreferences
        return encryptPrefs.getString("access_token", null)
    }

    fun isTokenExpired(): Boolean {
        val expiresAt = encryptPrefs.getLong("expires_at", 0)
        return System.currentTimeMillis() > expiresAt
    }
}

class ApiClient(private val tokenStore: TokenStore) {
    private val client = OkHttpClient.Builder()
        .addInterceptor(AuthInterceptor(tokenStore))
        .build()

    fun fetchUserProfile(): UserProfile? {
        val request = Request.Builder()
            .url("https://api.example.com/user/profile")
            .get()
            .build()

        val response = client.newCall(request).execute()
        return if (response.isSuccessful) {
            parseProfile(response.body?.string() ?: return null)
        } else null
    }
}

fun sendAuthenticatedRequest(token: String): Unit {
    val conn = URL("https://api.example.com/data").openConnection() as HttpURLConnection
    conn.setRequestProperty("Authorization", "Bearer $token")
    conn.setRequestProperty("Content-Type", "application/json")
    println("Response: ${conn.responseCode}")
}

예제에서는 두 가지 접근 방식을 보여줍니다. 자동 토큰 관리를 위한 OkHttp Interceptor 사용과 HttpURLConnection을 통한 직접 전송입니다. OkHttp Interceptor가 선호됩니다. 토큰 추가 및 갱신 로직을 중앙 집중화하여 각 요청에서 코드 중복을 제거합니다. 모든 요청은 단일 인터셉터를 통과하며, 응답 상태를 확인하고 필요 시 개발자 개입 없이 토큰을 갱신합니다.

자주 묻는 질문

Access token과 API key의 차이점은 무엇인가요?

API key는 특정 사용자에게 연결되지 않은 정적 애플리케이션 식별자입니다. Access token은 동적이며 일시적이고 사용자와 세션에 연결됩니다. API key는 scope(권한 제한)를 지원하지 않지만, access token은 작업별로 다른 액세스 수준을 가질 수 있습니다.

Access token이 만료되었는지 어떻게 알 수 있나요?

두 가지 방법이 있습니다. 능동적 방법—JWT의 exp 필드 확인(클라이언트가 토큰 만료 여부를 자체 계산). 수동적 방법—요청을 보내고 HTTP 401 Unauthorized를 수신. 두 가지를 결합하는 것이 좋습니다. 데이터 손실을 방지하기 위한 사전 exp 확인과 폴백으로서의 401 처리를 권장합니다.

URL에서 access token을 사용할 수 있나요?

아니요. Access token을 URL 쿼리 문자열로 전달해서는 안 됩니다. URL 매개변수는 브라우저 기록, 서버 로그, 리퍼러 및 프록시 서버 캐시에 저장됩니다. 유일한 안전한 방법은 Authorization: Bearer 헤더입니다. 이는 OAuth 2.0 Security Best Practices(RFC 9700)의 요구 사항입니다.

모바일 앱에 최적의 access token 수명은 얼마인가요?

15~30분을 권장합니다. 자동 갱신을 위해 로테이션이 있는 refresh token이 사용됩니다. 이 TTL은 보안과 UX의 균형을 유지합니다. 사용자는 갱신을 인지하지 못하며, 유출된 토큰에 대한 공격 창은 최소화됩니다. 특히 민감한 작업(송금)의 경우 1~5분입니다.

Bearer token이란 무엇인가요?

Bearer token은 토큰을 제시하는 사람(bearer)이 누구든 액세스 권한을 얻는 access token의 한 유형입니다. 소유권에 대한 암호학적 증명이 필요하지 않으며, 토큰을 전송하는 것만으로 충분합니다. Bearer 스키마는 간단하고 효과적이지만, 전송 중 토큰 가로채기로부터 보호하기 위해 HTTPS가 필요합니다.

요약

  • Access Token—보호된 API에 액세스하기 위한 임시 자격 증명
  • Bearer 스키마—각 HTTP 요청과 함께 Authorization 헤더로 토큰 전송
  • Opaque vs JWT—취소 용이성(opaque)과 성능(JWT) 사이의 선택
  • 짧은 TTL—손상 시 피해 최소화를 위한 15~30분
  • 안전한 저장—iOS의 Keychain, Android의 EncryptedSharedPreferences
  • Scope—access token은 권한이 부여된 작업 범위 내에서 액세스 권한을 제한
  • HTTPS 필수—암호화 없이 Bearer token 도난이 몇 초 만에 가능

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기