개요
세분화된 권한을 통해 소비자는 각 앱과 공유할 계정 데이터를 더 세부적으로 제어할 수 있습니다. 세분화된 권한은 더 세부적인 제어, 투명성, 보안을 제공하여 사용자와 개발자 모두에게 이점을 제공합니다. 이 가이드는 세분화된 권한을 처리하도록 애플리케이션을 성공적으로 업데이트하는 데 필요한 변경사항과 단계를 이해하는 데 도움이 됩니다.
세분화된 권한이란 무엇인가요?
이메일 및 캘린더 범위를 모두 요청하는 생산성 앱을 개발한다고 가정해 보겠습니다. 사용자가 Gmail이 아닌 Google Calendar에만 애플리케이션을 사용하려고 할 수 있습니다. 세분화된 OAuth 권한을 사용하면 사용자는 Google Calendar 권한만 부여하고 Gmail 권한은 부여하지 않을 수 있습니다. 사용자가 특정 데이터에 대한 액세스 권한을 부여할 수 있도록 함으로써 데이터 노출을 최소화하고 신뢰를 강화하며 사용자에게 디지털 생활에 대한 개인 정보 보호 우선 제어 기능을 제공합니다. 이러한 시나리오를 처리하도록 애플리케이션을 설계하는 것이 중요합니다.
로그인 이외의 범위가 두 개 이상 요청된 경우
로그인 및 비로그인 범위
로그인 범위와 로그인 이외의 범위를 모두 요청하는 애플리케이션의 경우 사용자에게 먼저 로그인 범위 (email, profile, openid)에 대한 사용자 동의 페이지가 표시됩니다. 사용자가 기본 ID 정보(이름, 이메일 주소, 프로필 사진)를 공유하는 데 동의하면 로그인 이외의 범위에 대한 세분화된 권한 동의 화면이 표시됩니다. 이 경우 애플리케이션은 사용자가 부여한 범위를 확인해야 하며 사용자가 요청된 모든 범위를 부여한다고 가정할 수 없습니다. 다음 예에서 웹 애플리케이션은 세 가지 로그인 범위와 Google Drive 비로그인 범위를 모두 요청합니다. 사용자가 로그인 범위에 동의하면 Google Drive 권한에 대한 세분화된 권한 동의 화면이 표시됩니다.
로그인 이외의 범위가 2개 이상인 경우
애플리케이션이 로그인 이외의 범위를 두 개 이상 요청하면 세분화된 권한 동의 화면이 사용자에게 표시됩니다. 사용자는 애플리케이션과 공유하기 위해 승인할 권한을 선택할 수 있습니다. 다음은 사용자의 Gmail 메시지 및 Google Calendar 데이터에 대한 액세스를 요청하는 세분화된 권한 동의 화면의 예입니다.
로그인 범위 (email, profile, openid)만 요청하는 애플리케이션의 경우 세분화된 권한 동의 화면이 적용되지 않습니다. 사용자는 전체 로그인 요청을 승인하거나 거부합니다. 즉, 애플리케이션이 로그인 범위 (1개, 2개 또는 3개 모두)만 요청하는 경우 세분화된 권한 동의 화면이 적용되지 않습니다.
로그인 이외의 범위를 하나만 요청하는 애플리케이션의 경우 세분화된 권한 동의 화면이 적용되지 않습니다. 즉, 사용자는 전체 요청을 승인하거나 거부하며 동의 화면에 체크박스가 없습니다. 다음 표에는 세분화된 권한 동의 화면이 표시되는 경우가 요약되어 있습니다.
| 로그인 범위 수 | 비로그인 범위 수 | 세분화된 권한 동의 화면 |
|---|---|---|
| 1-3 | 0 | 해당 없음 |
| 1-3 | 1+ | 적용 가능 |
| 0 | 1 | 해당 없음 |
| 0 | 2+ | 적용 가능 |
애플리케이션이 영향을 받는지 확인
권한 요청에 Google OAuth 2.0 승인 엔드포인트가 사용되는 애플리케이션 내의 모든 섹션을 철저히 검토합니다. 여러 범위를 요청하는 앱은 사용자에게 세분화된 권한 동의 화면을 표시하므로 주의를 기울이세요. 이러한 경우 사용자가 일부 범위만 승인하는 경우를 코드가 처리할 수 있는지 확인하세요.
애플리케이션에서 여러 범위를 사용하는지 확인하는 방법
앱 코드 또는 발신 네트워크 호출을 검사하여 앱에서 실행하는 Google OAuth 2.0 승인 요청으로 인해 세분화된 권한 동의 화면이 표시되는지 확인합니다.
애플리케이션 코드 검사
Google OAuth 승인 엔드포인트를 호출하여 사용자에게 권한을 요청하는 애플리케이션 코드 섹션을 검토합니다. Google API 클라이언트 라이브러리 중 하나를 사용하는 경우 클라이언트 초기화 단계에서 애플리케이션이 요청하는 범위를 확인할 수 있습니다. 다음 섹션에 몇 가지 예시가 나와 있습니다. 애플리케이션이 영향을 받는지 확인하려면 다음 예시에 표시된 안내를 참고하여 애플리케이션에서 Google OAuth 2.0을 처리하는 데 사용하는 SDK의 문서를 참조해야 합니다.
Google 아이덴티티 서비스
다음 Google 아이덴티티 서비스 JavaScript 라이브러리 코드 스니펫은 로그인이 아닌 여러 범위로 TokenClient를 초기화합니다.
웹 앱이 사용자에게 승인을 요청하면 세분화된 권한 동의 화면이 표시됩니다.
const client = google.accounts.oauth2.initTokenClient({ client_id: 'YOUR_CLIENT_ID', scope: 'https://www.googleapis.com/auth/calendar.readonly \ https://www.googleapis.com/auth/contacts.readonly', callback: (response) => { ... }, });
Python
다음 코드 스니펫은 google-auth-oauthlib.flow 모듈을 사용하여 승인 요청을 구성합니다. scope 매개변수에는 로그인 이외의 범위 두 개가 포함됩니다. 웹 애플리케이션이 사용자에게 승인을 요청하면 세분화된 권한 동의 화면이 표시됩니다.
import google.oauth2.credentials import google_auth_oauthlib.flow # Use the client_secret.json file to identify the application requesting # authorization. The client ID (from that file) and access scopes are # required. flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=[ 'https://www.googleapis.com/auth/calendar.readonly', 'https://www.googleapis.com/auth/contacts.readonly' ])
Node.js
다음 코드 스니펫은 google.auth.OAuth2 객체를 만듭니다. 이 객체는 승인 요청의 매개변수를 정의하며, 이 요청의 scope 매개변수에는 로그인 이외의 범위 두 개가 포함됩니다. 웹 앱이 사용자에게 승인을 요청하면 세분화된 권한 동의 화면이 표시됩니다.
const {google} = require('googleapis'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, * CLIENT_SECRET, AND REDIRECT_URI from the client_secret.json file. To get * these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for read-only Calendar and Contacts. const scopes = [ 'https://www.googleapis.com/auth/calendar.readonly', 'https://www.googleapis.com/auth/contacts.readonly'] ]; // Generate a url that asks permissions const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined earlier. * Alternatively, if only one scope is needed, you can pass a scope URL * as a string */ scope: scopes, // Enable incremental authorization. Recommended as best practices. include_granted_scopes: true });
발신 네트워크 호출 검사
네트워크 호출을 검사하는 방법은 애플리케이션 유형에 따라 다릅니다.
- 웹 애플리케이션 - Chrome에서 네트워크 활동 검사
- Android - 네트워크 검사기로 네트워크 트래픽 검사
- Chrome 앱
- Chrome 확장 프로그램 페이지로 이동합니다.
- 확장 프로그램 페이지의 오른쪽 상단에 있는 개발자 모드 체크박스를 선택합니다.
- 모니터링할 확장 프로그램 선택
- 확장 프로그램 페이지의 뷰 검사 섹션에서 백그라운드 페이지 링크를 클릭합니다.
- 개발자 도구 대화상자가 열리면 네트워크 탭에서 네트워크 트래픽을 모니터링할 수 있습니다.
- iOS - Instruments를 사용하여 HTTP 트래픽 분석
- 데스크톱 앱 - 앱이 개발된 운영체제에 사용할 수 있는 네트워크 캡처 도구를 사용합니다.
네트워크 호출을 검사하는 동안 Google OAuth 승인 엔드포인트로 전송된 요청을 찾고 scope 매개변수를 검사합니다.
이러한 값은 세분화된 권한 동의 화면을 표시합니다.
scope매개변수에는 로그인 범위와 비로그인 범위가 포함됩니다.다음 샘플 요청에는 세 가지 로그인 범위와 사용자의 Google Drive 파일 메타데이터를 볼 수 있는 로그인 범위가 아닌 범위가 하나 포함되어 있습니다.
https://accounts.google.com/o/oauth2/v2/auth? access_type=offline& scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly& include_granted_scopes=true& response_type=code& redirect_uri=YOUR_REDIRECT_URL& client_id=YOUR_CLIENT_ID
scope매개변수에 로그인 이외의 범위가 두 개 이상 포함되어 있습니다.다음 샘플 요청에는 사용자의 Google Drive 메타데이터를 보고 특정 Google Drive 파일을 관리하는 두 개의 비로그인 범위가 포함되어 있습니다.
https://accounts.google.com/o/oauth2/v2/auth? access_type=offline& scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file& include_granted_scopes=true& response_type=code& redirect_uri=YOUR_REDIRECT_URL& client_id=YOUR_CLIENT_ID
세분화된 권한 처리를 위한 권장사항
애플리케이션을 업데이트하여 세분화된 권한을 처리해야 한다고 판단하는 경우 여러 범위에 대한 동의를 올바르게 처리하도록 코드를 업데이트해야 합니다. 모든 애플리케이션은 다음 권장사항을 준수해야 합니다.
- Google API 서비스: 사용자 데이터 정책을 검토하고 이를 준수하는지 확인합니다.
- 작업에 필요한 특정 범위 요청 필요한 범위만 요청하는 Google OAuth 2.0 정책을 준수해야 합니다. 앱의 핵심 기능에 필수적이지 않은 한 로그인 시 여러 범위를 요청하지 않아야 합니다. 특히 애플리케이션 기능에 익숙하지 않은 최초 사용자의 경우 여러 범위를 함께 번들로 묶으면 이러한 권한의 필요성을 이해하기 어려울 수 있습니다. 이로 인해 경고가 발생하고 사용자가 애플리케이션에 더 이상 참여하지 않을 수 있습니다.
- 승인 요청을 하기 전에 사용자에게 근거를 제공합니다. 애플리케이션에 요청된 권한이 필요한 이유, 사용자의 데이터로 수행할 작업, 요청을 승인하면 사용자에게 어떤 이점이 있는지 명확하게 설명합니다. Google의 연구에 따르면 이러한 설명은 사용자의 신뢰와 참여를 높입니다.
- 여러 액세스 토큰을 관리할 필요가 없도록 애플리케이션에서 범위를 요청할 때마다 점진적 승인을 사용합니다.
- 사용자가 부여한 범위를 확인합니다. 한 번에 여러 범위를 요청하는 경우 사용자가 앱에서 요청하는 모든 범위를 부여하지 않을 수 있습니다. 앱은 항상 사용자가 부여한 범위를 확인하고 관련 기능을 사용 중지하여 범위 거부를 처리해야 합니다. 여러 범위에 대한 동의 처리에 관한 Google OAuth 2.0 정책을 따르고, 사용자가 해당 범위가 필요한 특정 기능을 사용하겠다는 의도를 명확히 표시한 경우에만 사용자에게 다시 동의를 요청합니다.
세분화된 권한을 처리하도록 애플리케이션 업데이트
Android 애플리케이션
Google OAuth 2.0과 상호작용하는 데 사용하는 SDK의 문서를 참고하고 권장사항에 따라 세분화된 권한을 처리하도록 애플리케이션을 업데이트해야 합니다.
Play 서비스의 auth.api.signin SDK를 사용하여 Google OAuth 2.0과 상호작용하는 경우 requestPermissions 함수를 사용하여 필요한 최소 범위 집합을 요청하고 hasPermissions 함수를 사용하여 세분화된 권한을 요청할 때 사용자가 부여한 범위를 확인할 수 있습니다.
Chrome 확장 프로그램 애플리케이션
권장사항에 따라 Google OAuth 2.0을 사용하려면 Chrome Identity API를 사용해야 합니다.
다음 예는 세분화된 권한을 올바르게 처리하는 방법을 보여줍니다.
manifest.json
예시 매니페스트 파일은 Chrome 확장 프로그램 애플리케이션에 대해 로그인 이외의 범위 두 개를 선언합니다.
{
"name": "Example Chrome extension application",
...
"permissions": [
"identity"
],
"oauth2" : {
"client_id": "YOUR_CLIENT_ID",
"scopes":[
"https://www.googleapis.com/auth/calendar.readonly",
"https://www.googleapis.com/auth/contacts.readonly"
]
}
}잘못된 접근 방식
전부 아니면 전무
사용자가 버튼을 클릭하여 승인 프로세스를 시작합니다. 코드 스니펫은 manifest.json 파일에 지정된 두 범위에 대해 사용자에게 '전부 아니면 전무' 동의 화면이 표시된다고 가정합니다. 사용자가 부여한 범위를 확인하지 않습니다.
oauth.js
...
document.querySelector('button').addEventListener('click', function () {
chrome.identity.getAuthToken({ interactive: true },
function (token) {
if (token === undefined) {
// User didn't authorize both scopes.
// Updating the UX and application accordingly
...
} else {
// User authorized both or one of the scopes.
// It neglects to check which scopes users granted and assumes
// users granted all scopes.
// Calling the APIs, etc.
...
}
});
});
올바른 접근 방식
최소 범위
필요한 가장 작은 범위 집합을 선택하세요.
애플리케이션은 필요한 최소 범위 집합만 요청해야 합니다. 애플리케이션이 작업을 완료하는 데 필요한 경우 한 번에 하나의 범위를 요청하는 것이 좋습니다.
이 예시에서는 manifest.json 파일에 선언된 두 범위가 모두 필요한 최소 범위 집합이라고 가정합니다. oauth.js 파일은 Chrome Identity API를 사용하여 Google에서 승인 프로세스를 시작합니다. 사용자가 애플리케이션에 권한을 부여하는 것을 더 세부적으로 제어할 수 있도록 세분화된 권한을 사용 설정해야 합니다. 애플리케이션은 사용자가 승인하는 범위를 확인하여 사용자의 응답을 적절하게 처리해야 합니다.
oauth.js
...
document.querySelector('button').addEventListener('click', function () {
chrome.identity.getAuthToken(
{ interactive: true, enableGranularPermissions: true },
function (token, grantedScopes) {
if (token === undefined) {
// User didn't authorize any scope.
// Updating the UX and application accordingly
...
} else {
// User authorized the request. Now, check which scopes were
// granted.
if (grantedScopes.includes(
'https://www.googleapis.com/auth/calendar.readonly'))
{
// User authorized Calendar read permission.
// Calling the APIs, etc.
...
}
else
{
// User didn't authorize Calendar read permission.
// Update UX and application accordingly
...
}
if (grantedScopes.includes(
'https://www.googleapis.com/auth/contacts.readonly'))
{
// User authorized Contacts read permission.
// Calling the APIs, etc.
...
}
else
{
// User didn't authorize Contacts read permission.
// Update UX and application accordingly
...
}
}
});
});
iOS, iPadOS, macOS 애플리케이션
Google OAuth 2.0과 상호작용하는 데 사용하는 SDK의 문서를 참고하고 권장사항에 따라 세분화된 권한을 처리하도록 애플리케이션을 업데이트해야 합니다.
iOS 및 macOS용 Google 로그인 라이브러리를 사용하여 Google OAuth 2.0과 상호작용하는 경우 세분화된 권한 처리에 관한 문서를 검토해야 합니다.
웹 애플리케이션
Google OAuth 2.0과 상호작용하는 데 사용하는 SDK의 문서를 참고하고 권장사항에 따라 세분화된 권한을 처리하도록 애플리케이션을 업데이트해야 합니다.
서버 측 (오프라인) 액세스
서버 측 (오프라인) 액세스 모드를 사용하려면 다음을 수행해야 합니다.
- 서버를 설정하고 승인 코드를 수신할 공개적으로 액세스 가능한 엔드포인트를 정의합니다.
- Google Cloud 콘솔의 클라이언트 페이지에서 공개 엔드포인트의 리디렉션 URI를 구성합니다.
다음 코드 스니펫은 로그인 이외의 범위 두 개를 요청하는 NodeJS 예시를 보여줍니다. 사용자에게 세분화된 권한 동의 화면이 표시됩니다.
잘못된 접근 방식
전부 아니면 전무
사용자가 승인 URL로 리디렉션됩니다. 코드 스니펫은 scopes 배열에 지정된 두 범위에 대해 사용자에게 '전부 아니면 전무' 동의 화면이 표시된다고 가정합니다. 사용자가 부여한 범위를 확인하지 않습니다.
main.js
...
const oauth2Client = new google.auth.OAuth2(
YOUR_CLIENT_ID,
YOUR_CLIENT_SECRET,
YOUR_REDIRECT_URL
);
// Access scopes for two non-Sign-In scopes - Google Calendar and Contacts
const scopes = [
'https://www.googleapis.com/auth/contacts.readonly',
'https://www.googleapis.com/auth/calendar.readonly'
];
// Generate a url that asks permissions for the Google Calendar and Contacts
// scopes
const authorizationUrl = oauth2Client.generateAuthUrl({
// 'online' (default) or 'offline' (gets refresh_token)
access_type: 'offline',
// Pass in the scopes array defined earlier
scope: scopes,
// Enable incremental authorization. Recommended as best practices.
include_granted_scopes: true
});
async function main() {
const server = http.createServer(async function (req, res) {
// Example on redirecting user to the Google authorization server.
if (req.url == '/') {
res.writeHead(301, { "Location": authorizationUrl });
}
// Receive the callback from the Google authorization server.
if (req.url.startsWith('/oauth2callback')) {
// Handle the Google authorization server response
let q = url.parse(req.url, true).query;
if (q.error) {
// User didn't authorize both scopes.
// Updating the UX and application accordingly
...
} else {
// User authorized both or one of the scopes.
// It neglects to check which scopes users granted and assumes users
// granted all scopes.
// Get access and refresh tokens (if access_type is offline)
let { tokens } = await oauth2Client.getToken(q.code);
// Calling the APIs, etc.
...
}
}
res.end();
}).listen(80);
}
올바른 접근 방식
최소 범위
필요한 가장 작은 범위 집합을 선택하세요.
애플리케이션은 필요한 최소 범위 집합만 요청해야 합니다. 애플리케이션이 작업을 완료하는 데 필요한 경우 한 번에 하나의 범위를 요청하는 것이 좋습니다. 애플리케이션이 범위를 요청할 때마다 점진적 승인을 사용하여 여러 액세스 토큰을 관리하지 않아도 됩니다.
애플리케이션에서 로그인이 아닌 범위를 여러 개 요청해야 하는 경우 요청 시 항상 점진적 승인을 사용하고 사용자가 부여한 범위를 확인해야 합니다.
이 예시에서는 앱이 제대로 작동하려면 명시된 두 범위가 모두 필요하다고 가정합니다. 사용자가 애플리케이션에 권한을 부여하는 것을 더 세밀하게 제어할 수 있도록 세분화된 권한을 사용 설정해야 합니다. 애플리케이션은 사용자가 승인한 범위를 확인하여 사용자의 응답을 적절하게 처리해야 합니다.
main.js
...
const oauth2Client = new google.auth.OAuth2(
YOUR_CLIENT_ID,
YOUR_CLIENT_SECRET,
YOUR_REDIRECT_URL
);
// Access scopes for two non-Sign-In scopes - Google Calendar and Contacts
const scopes = [
'https://www.googleapis.com/auth/contacts.readonly',
'https://www.googleapis.com/auth/calendar.readonly'
];
// Generate a url that asks permissions for the Google Calendar and Contacts
// scopes
const authorizationUrl = oauth2Client.generateAuthUrl({
// 'online' (default) or 'offline' (gets refresh_token)
access_type: 'offline',
// Pass in the scopes array defined earlier
scope: scopes,
// Enable incremental authorization. Recommended as best practices.
include_granted_scopes: true,
// Set to true to enable more granular permissions for Google OAuth 2.0
// client IDs created before 2019. No effect for newer Google OAuth 2.0
// client IDs, since more granular permissions is always enabled for them.
enable_granular_consent: true
});
async function main() {
const server = http.createServer(async function (req, res) {
// Redirect users to the Google authorization server.
if (req.url == '/') {
res.writeHead(301, { "Location": authorizationUrl });
}
// Receive the callback from the Google authorization server.
if (req.url.startsWith('/oauth2callback')) {
// Handle the Google authorization server response
let q = url.parse(req.url, true).query;
if (q.error) {
// User didn't authorize both scopes.
// Updating the UX and application accordingly
...
} else {
// Get access and refresh tokens (if access_type is offline)
let { tokens } = await oauth2Client.getToken(q.code);
oauth2Client.setCredentials(tokens);
// User authorized the request. Now, check which scopes were
// granted.
if (tokens.scope.includes(
'https://www.googleapis.com/auth/calendar.readonly'))
{
// User authorized Calendar read permission.
// Calling the APIs, etc.
...
}
else
{
// User didn't authorize Calendar read permission.
// Calling the APIs, etc.
...
}
// Check which scopes user granted the permission to application
if (tokens.scope.includes(
'https://www.googleapis.com/auth/contacts.readonly'))
{
// User authorized Contacts read permission.
// Calling the APIs, etc.
...
}
else
{
// User didn't authorize Contacts read permission.
// Update UX and application accordingly
...
}
}
}
res.end();
}).listen(80);
}
서버 기반 애플리케이션에서 Google API에 액세스하는 방법에 관한 서버 측 웹 앱 가이드를 검토합니다.
클라이언트 측 전용 액세스
- Google 아이덴티티 서비스 JavaScript 라이브러리를 사용하여 Google OAuth 2.0과 상호작용하는 애플리케이션의 경우 세분화된 권한 처리에 관한 이 문서를 검토해야 합니다.
- JavaScript를 사용하여 Google OAuth 2.0 승인 엔드포인트를 직접 호출하는 애플리케이션의 경우 세분화된 권한 처리에 관한 이 문서를 검토해야 합니다.
세분화된 권한 처리에 관해 업데이트된 애플리케이션 테스트
- 사용자가 권한 요청에 응답할 수 있는 모든 사례와 애플리케이션에서 예상되는 동작을 설명합니다. 예를 들어 사용자가 요청된 범위 3개 중 2개만 승인하는 경우 애플리케이션은 이에 따라 작동해야 합니다.
세분화된 권한이 사용 설정된 상태에서 애플리케이션을 테스트합니다. 세분화된 권한을 사용 설정하는 방법에는 두 가지가 있습니다.
- 애플리케이션의 OAuth 2.0 동의 화면을 확인하여 애플리케이션에 세분화된 권한이 이미 사용 설정되어 있는지 확인합니다. 테스트 목적으로 Google Cloud 콘솔을 통해 새 웹, Android 또는 iOS Google OAuth 2.0 클라이언트 ID를 만들 수도 있습니다. 이러한 ID에는 세분화된 권한이 항상 사용 설정되어 있기 때문입니다.
Google OAuth 승인 엔드포인트를 호출할 때
enable_granular_consent매개변수를true로 설정합니다. 일부 SDK는 이 매개변수를 명시적으로 지원합니다. 다른 경우에는 문서를 확인하여 이 매개변수와 해당 값을 수동으로 추가하는 방법을 확인하세요. 구현에서 매개변수 추가를 지원하지 않는 경우 이전 포인트에 설명된 대로 테스트 목적으로만 Google Cloud 콘솔을 통해 새 웹, Android 또는 iOS Google OAuth 2.0 클라이언트 ID를 만들 수 있습니다.
업데이트된 애플리케이션을 테스트할 때는 Workspace 계정 대신 개인 Google 계정(@gmail.com)을 사용하세요. 이는 전체 도메인 위임이 있거나 신뢰할 수 있음으로 표시된 Workspace Enterprise 앱이 현재 세분화된 권한 변경의 영향을 받지 않기 때문입니다. 따라서 조직의 Workspace 계정으로 테스트하면 의도한 대로 새로운 세분화된 동의 화면이 표시되지 않을 수 있습니다.