클라이언트 ID가 승인되지 않은 경우 7일 후에 갱신 토큰이 작동하지 않을 수 있습니다. 7일 토큰 만료는 상업용 또는 샌드박스 승인과 관련이 없습니다. 서비스 또는 사용자 계정의 OAuth 2.0 클라이언트 ID가 승인되고 프로덕션에 배치되어야 토큰 수명이 길어집니다.
자세한 내용은 갱신 토큰 만료를 참고하세요.
액세스가 거부됨
Google Cloud에서 OAuth 동의 화면을 설정했고 사용자 유형이 External인 경우 앱의 테스트 사용자로 등록되지 않은 Google 계정으로 계정 연결을 시도하면 '액세스 거부됨' 오류가 표시됩니다. OAuth 동의 화면의 테스트 사용자 섹션에 Google 계정을 추가해야 합니다.
SDM API는 제한된 범위를 사용합니다. 즉, 승인 중에 이 범위를 사용하는 앱은 OAuth API 확인이 완료되지 않는 한 '확인되지 않음'으로 표시됩니다. 개인용으로 Device Access 을 사용하는 경우 OAuth API 인증이 필요하지 않습니다.
인증 프로세스 중에 'Google에서 이 앱을 인증하지 않았습니다' 화면이 표시될 수 있습니다. 이 화면은 Google Cloud의 OAuth 동의 화면에 sdm.service 범위가 구성되지 않은 경우 표시됩니다. 고급 옵션을 클릭한 다음 프로젝트 이름으로 이동 (안전하지 않음)을 클릭하면 이 화면을 건너뛸 수 있습니다.
액세스 또는 새로고침 토큰을 가져오려고 할 때 잘못된 OAuth 2.0 클라이언트 보안 비밀을 제공하면 '잘못된 클라이언트' 오류가 표시됩니다. 액세스 및 갱신 토큰 호출에 사용하는 client_secret 값이 Google Cloud 사용자 인증 정보 페이지에 표시된 OAuth 2.0 클라이언트 ID의 값인지 확인합니다.
잘못된 요청, 필수 범위가 누락됨
PCM에서 권한을 부여한 후 '필수 매개변수 범위가 누락됨'이라는 '잘못된 요청' 오류가 발생할 수 있습니다. 승인 호출에 사용하는 scope 값이 Google Cloud 사용자 인증 정보 페이지에 표시된 OAuth 2.0 클라이언트에 설정된 값과 동일한지 확인합니다.
리디렉션 URI 불일치
승인 절차를 진행할 때 '리디렉션 URI 불일치' 오류가 발생할 수 있습니다. 승인 호출에 사용하는 redirect_uri 값이 Google Cloud 사용자 인증 정보 페이지에 표시된 OAuth 2.0 클라이언트에 설정된 값과 동일한지 확인합니다.
빠른 참조
이 참조를 사용하여user 를 승인하고 Google 계정을 연결하는 단계를 빠르게 구현하세요.
이 빠른 참조를 사용하려면 코드 샘플의 각 자리표시자 변수를 특정 통합의 값으로 수정하고 필요에 따라 복사하여 붙여넣으세요.
[null,null,["최종 업데이트: 2025-07-29(UTC)"],[[["\u003cp\u003eThis guide helps troubleshoot common errors during the Google OAuth authorization process for the Smart Device Management (SDM) API.\u003c/p\u003e\n"],["\u003cp\u003eRefresh tokens might expire after 7 days if the client ID is not approved for production.\u003c/p\u003e\n"],["\u003cp\u003e"Access denied" errors can occur when using external user types if the Google account isn't listed as a test user.\u003c/p\u003e\n"],["\u003cp\u003eAn "unverified app" screen might appear if using restricted scopes without OAuth API verification, but this can be bypassed for personal use.\u003c/p\u003e\n"],["\u003cp\u003eSeveral errors, such as "Invalid client," "Invalid request," and "Redirect uri mismatch," can arise from incorrect OAuth 2.0 Client ID or Secret values.\u003c/p\u003e\n"]]],["Google OAuth errors include: expiring refresh tokens (resolve by client ID approval), \"Access denied\" (add account to test users), \"Google hasn't verified this app\" (bypass via \"Advanced\"), \"Invalid client\" (verify Client Secret), \"Invalid request\" (check scope), and \"Redirect URI mismatch\" (ensure URI consistency). Authorization requires directing users to PCM, obtaining an authorization code, using the code to get access/refresh tokens, making an initial API call and using refresh tokens to acquire new access tokens.\n"],null,["# Authorization Errors\n\nDuring the authorization process, Google OAuth may return an error. Use this\nguide to troubleshoot the most common errors during this process.\n\nTroubleshooting\n---------------\n\nTo learn more about Google OAuth, see [Using OAuth 2.0 to Access Google\nAPIs](https://developers.google.com/identity/protocols/oauth2).\n\n### Refresh token keeps expiring\n\nRefresh tokens can stop working after 7 days if the client ID is not approved is\none possible cause. The 7-day token expiration is not related to Commercial\nor Sandbox approvals. A service or user account needs to get their OAuth\n2.0 client ID approved and put into production to get longer token lifespans.\nSee [Refresh token expiration](/identity/protocols/oauth2#expiration) for more\ninformation.\n\n### Access denied\n\nIf you've set up your [OAuth consent screen](https://console.developers.google.com/apis/credentials/consent/edit) in Google Cloud and\nthe **User type** is **External** , you will get an \"Access denied\" error if you\nattempt to account link with a Google account that is not listed as a test user\nfor your app. Make sure to add the Google account to the **Test users** section\nin your [OAuth consent screen](https://console.developers.google.com/apis/credentials/consent/edit).\n\n### Partner Connections Manager (PCM) error\n\nFor help with any errors encountered when accessing\nPCM, see\n[Partner Connections Manager (PCM)\nError Reference](/nest/device-access/reference/errors/pcm).\n\n### Google hasn't verified this app\n\nThe SDM API uses a restricted scope, which means that any\napps that use this scope during authorization will be \"unverified\" unless\n[OAuth API Verification](https://developers.googleblog.com/2019/09/get-smart-about-preparing-your-app-for-OAuth-verfication.html) is completed. **When using Device Access for\npersonal use, OAuth API Verification is not required.**\n\nYou may see a \"Google hasn't verified this app\" screen during the authorization\nprocess, which appears if the `sdm.service` scope is not configured on\nyour [OAuth consent screen](https://console.developers.google.com/apis/credentials/consent/edit) in Google Cloud. This screen can be\nbypassed by clicking the **Advanced** option and then clicking **Go to *Project\nName* (unsafe)**.\n\nSee [Unverified app\nscreen](https://support.google.com/cloud/answer/7454865#unverified-app-screen)\nfor more information.\n\n### Invalid client\n\nWhen attempting to get an access or refresh token, you will get an \"Invalid\nclient\" error if you provide an incorrect OAuth 2.0 Client Secret. Make sure the\n`client_secret` value you're using in access and refresh token calls is the one\nfor the OAuth 2.0 Client ID being used, as found in your\n[Google Cloud\nCredentials](https://console.developers.google.com/apis/credentials)\npage.\n\n### Invalid request, missing required scope\n\nAfter granting permissions in PCM, you might run into a\n\"Invalid request\" error of \"Missing required parameter: scope\". Make sure the\n`scope` value you're using in authorization calls is the same as the one you set for the OAuth 2.0 Client,\nas found in your [Google Cloud\nCredentials](https://console.developers.google.com/apis/credentials)\npage.\n\n### Redirect uri mismatch\n\nWhen going through authorization, you might run into a \"Redirect uri mismatch\"\nerror. Make sure the `redirect_uri` value you're using in authorization calls is\nthe same as the one you set for the OAuth 2.0 Client, as found in your\n[Google Cloud\nCredentials](https://console.developers.google.com/apis/credentials)\npage.\n\nQuick reference\n---------------\n\nUse this reference to quickly implement the steps to authorize a\nuser and link their Google account\n.\n\nTo use this quick reference, edit each placeholder variable in the code samples\nwith the values for your specific integration, and copy and paste as needed: \n\n### 1 PCM\n\nDirect the user to the PCM link in your\napp, replacing:\n\n1. \u003cvar translate=\"no\"\u003eproject-id\u003c/var\u003e with your Device Access Project ID\n2. \u003cvar translate=\"no\"\u003eoauth2-client-id\u003c/var\u003e with the OAuth2 Client ID from your [Google Cloud\n Credentials](https://console.developers.google.com/apis/credentials)\n3. \u003cvar translate=\"no\"\u003eredirect-uri\u003c/var\u003e with a Redirect URI specified for the OAuth2 Client ID you are using\n4. \u003cvar translate=\"no\"\u003escope\u003c/var\u003e with one of your [available\n scopes](#oauth_20_scopes)\n\n```\nhttps://nestservices.google.com/partnerconnections/project-id/auth?redirect_uri=redirect-uri&access_type=offline&prompt=consent&client_id=oauth2-client-id&response_type=code&scope=https://www.googleapis.com/auth/scope\n```\n\n### 2 Auth Code\n\nAfter granting permissions through PCM for\nyour selected scope, the user should be redirected to your specified Redirect\nURI. The Authorization Code is returned as the `code` parameter in the URL,\nwhich should be in this format:\n\n```\nredirect-uri?code=authorization-code&scope=https://www.googleapis.com/auth/scope\n```\n\n### 3 Access Token\n\nUse the authorization code to retrieve an access token, that\nyou can use to call the SDM API on\nbehalf of the user.\n\nMake a POST call to Google's OAuth\nendpoint, replacing:\n\n1. \u003cvar translate=\"no\"\u003eoauth2-client-id\u003c/var\u003e and \u003cvar translate=\"no\"\u003eoauth2-client-secret\u003c/var\u003e with the OAuth2 Client ID and Client Secret from your [Google Cloud\n Credentials](https://console.developers.google.com/apis/credentials)\n2. \u003cvar translate=\"no\"\u003eauthorization-code\u003c/var\u003e with the code you received in the previous step\n3. \u003cvar translate=\"no\"\u003eredirect-uri\u003c/var\u003e with a Redirect URI specified for the OAuth2 Client ID you are using\n\nGoogle OAuth returns two tokens, an access token and a\nrefresh token. \n\n### Request\n\n curl -L -X POST 'https://www.googleapis.com/oauth2/v4/token?client_id=\u003cvar translate=\"no\"\u003eoauth2-client-id\u003c/var\u003e&client_secret=\u003cvar translate=\"no\"\u003eoauth2-client-secret\u003c/var\u003e&code=\u003cvar translate=\"no\"\u003eauthorization-code\u003c/var\u003e&grant_type=authorization_code&redirect_uri=\u003cvar translate=\"no\"\u003eredirect-uri\u003c/var\u003e'\n\n### Response\n\n {\n \"access_token\": \"access-token\",\n \"expires_in\": 3599,\n \"refresh_token\": \"refresh-token\",\n \"scope\": \"https://www.googleapis.com/auth/scope\",\n \"token_type\": \"Bearer\"\n }\n\n### 4 API Call\n\nAuthorization is not complete until you make\nan API call with the user's access token. This\ninitial call finishes the authorization process and enables events.\n| **This call is required as part of authorization.** Until this call is made: \n|\n| - The authorized project will not appear on PCM.\n| - Events will not be published.\n\nYou **must** use one of the\nAPI calls listed for the specified scope to complete authorization.\n\n### sdm.service\n\n### devices\n\nSee the\n[`devices.list`](/nest/device-access/reference/rest/v1/enterprises.devices/list)\nAPI reference for more information. \n\n curl -X GET 'https://smartdevicemanagement.googleapis.com/v1/enterprises/\u003cvar translate=\"no\"\u003eproject-id\u003c/var\u003e/devices' \\\n -H 'Content-Type: application/json' \\\n -H 'Authorization: Bearer \u003cvar translate=\"no\"\u003eaccess-token\u003c/var\u003e'\n\n### 5 Refresh Token\n\nAccess tokens for the SDM API are only\nvalid for 1 hour, as noted in the `expires_in` parameter returned by Google OAuth. If\nyour access token expires, use the refresh token to get a new one.\n\nMake a POST call to Google's OAuth\nendpoint, replacing:\n\n1. \u003cvar translate=\"no\"\u003eoauth2-client-id\u003c/var\u003e and \u003cvar translate=\"no\"\u003eoauth2-client-secret\u003c/var\u003e with the OAuth2 Client ID and Client Secret from your [Google Cloud\n Credentials](https://console.developers.google.com/apis/credentials)\n2. \u003cvar translate=\"no\"\u003erefresh-token\u003c/var\u003e with the code you received when initially getting the access token.\n\nGoogle OAuth returns a new access token. \n\n### Request\n\n curl -L -X POST 'https://www.googleapis.com/oauth2/v4/token?client_id=\u003cvar translate=\"no\"\u003eoauth2-client-id\u003c/var\u003e&client_secret=\u003cvar translate=\"no\"\u003eoauth2-client-secret\u003c/var\u003e&refresh_token=\u003cvar translate=\"no\"\u003erefresh-token\u003c/var\u003e&grant_type=refresh_token'\n\n### Response\n\n {\n \"access_token\": \"new-access-token\",\n \"expires_in\": 3599,\n \"scope\": \"https://www.googleapis.com/auth/scope\",\n \"token_type\": \"Bearer\"\n }"]]