사용자 인증

웹 인증 프로토콜은 HTTP 기능을 활용하지만 Chrome 앱은 앱 컨테이너 내에서 실행됩니다. HTTP를 통해 로드되지 않으며 리디렉션을 실행하거나 쿠키를 설정할 수 없습니다.

Chrome ID API를 사용하여 사용자를 인증합니다. Google 계정에 로그인한 사용자의 경우 getAuthToken, Google 이외의 계정에 로그인한 사용자의 경우 launchWebAuthFlow를 사용합니다. 앱에서 자체 서버를 사용하여 사용자를 인증하는 경우 후자를 사용해야 합니다.

작동 방식

Chrome 앱 사용자의 프로필에는 Google 계정이 연결되어 있습니다. 앱은 getAuthToken API를 사용하여 이러한 사용자의 OAuth2 토큰을 가져올 수 있습니다.

Google 이외의 ID 공급자로 인증을 실행하려는 앱은 launchWebAuthFlow를 호출해야 합니다. 이 방법은 브라우저 팝업을 사용하여 제공업체 페이지를 표시하고 특정 URL 패턴으로의 리디렉션을 캡처합니다. 리디렉션 URL이 앱에 전달되고 앱은 URL에서 토큰을 추출합니다.

Google 계정 인증

다음은 완료해야 하는 5가지 단계입니다.

  1. 매니페스트에 권한을 추가하고 앱을 업로드합니다.
  2. 설치된 manifest.json의 키를 소스 매니페스트에 복사하여 개발 중에 애플리케이션 ID가 일정하게 유지되도록 합니다.
  3. Chrome 앱의 OAuth2 클라이언트 ID를 가져옵니다.
  4. 클라이언트 ID와 범위를 포함하도록 매니페스트를 업데이트합니다.
  5. 인증 토큰을 가져옵니다.

권한 추가 및 앱 업로드

매니페스트에 ID 권한이 있는지 확인해야 합니다. 그런 다음 앱 및 확장 프로그램 관리 페이지에 앱을 업로드할 수 있습니다 (게시 참고).

"permissions": [
  "identity"
]

매니페스트에 키 복사

Google OAuth Console에서 애플리케이션을 등록할 때 애플리케이션의 ID를 제공합니다. 이 ID는 토큰 요청 중에 확인됩니다. 따라서 개발 중에는 일관된 애플리케이션 ID를 사용하는 것이 중요합니다.

애플리케이션 ID를 일정하게 유지하려면 설치된 manifest.json의 키를 소스 매니페스트에 복사해야 합니다. 가장 우아한 방법은 아니지만 방법은 다음과 같습니다.

  1. 사용자 데이터 디렉터리로 이동합니다. MacOs의 예: ~/Library/Application\ Support/Google/Chrome/Default/Extensions
  2. 설치된 앱 및 확장 프로그램을 나열하고 앱 및 확장 프로그램 관리 페이지의 앱 ID를 여기의 동일한 ID와 일치시킵니다.
  3. 설치된 앱 디렉터리로 이동합니다 (앱 ID 내의 버전). 설치된 manifest.json를 엽니다 (pico는 파일을 빠르게 여는 방법입니다).
  4. 설치된 manifest.json에서 '키'를 복사하여 앱의 소스 매니페스트 파일에 붙여넣습니다.

OAuth2 클라이언트 ID 가져오기

클라이언트 ID를 가져오려면 Google API 콘솔에 앱을 등록해야 합니다.

  1. Chrome 웹 스토어에 앱을 업로드할 때 사용한 것과 동일한 Google 계정을 사용하여 Google APIs Console에 로그인합니다.
  2. 왼쪽 상단의 드롭다운 메뉴를 펼치고 만들기... 메뉴 항목을 선택하여 새 프로젝트를 만듭니다.
  3. 만들고 이름을 지정한 후 '서비스' 탐색 메뉴 항목으로 이동하여 앱에 필요한 Google 서비스를 사용 설정합니다.
  4. 'API 액세스' 탐색 메뉴 항목으로 이동하여 OAuth 2.0 클라이언트 ID 만들기... 파란색 버튼을 클릭합니다.
  5. 요청된 브랜딩 정보를 입력하고 설치된 애플리케이션 유형을 선택합니다.
  6. Chrome 애플리케이션을 선택하고 애플리케이션 ID (앱 및 확장 프로그램 관리 페이지에 표시된 것과 동일한 ID)를 입력합니다.

OAuth2 클라이언트 ID 및 범위로 매니페스트 업데이트

클라이언트 ID와 범위를 포함하도록 매니페스트를 업데이트해야 합니다. 다음은 gdrive 샘플의 샘플 'oauth2'입니다.

"oauth2": {
    "client_id": "665859454684.apps.googleusercontent.com",
    "scopes": [
      "https://www.googleapis.com/auth/drive"
    ]
  }

액세스 토큰 가져오기

이제 identity.getAuthToken을 호출하여 인증 토큰을 가져올 수 있습니다.

chrome.identity.getAuthToken({ 'interactive': true }, function(token) {
  // Use the token.
});

사용자 상호작용

getAuthToken를 호출할 때 API를 대화형 모드로 호출할지 또는 무음 모드로 호출할지 나타내는 플래그 (위 예에서는 'interactive': true)를 전달할 수 있습니다. 대화형 모드에서 API를 호출하면 필요한 경우 아래 스크린샷과 같이 사용자에게 로그인 또는 승인 UI가 표시됩니다.

앱이 Identity API를 사용하여 Google 계정을 인증할 때의 UI를 보여주는 스크린샷

자동 모드에서 API를 호출하면 API는 UI를 표시하지 않고 토큰을 생성할 수 있는 경우에만 토큰을 반환합니다. 이는 앱이 앱 시작 시 흐름을 실행하는 경우 또는 일반적으로 사용자 동작이 포함되지 않은 경우에 유용합니다.

권장사항은 사용자 동작이 없는 경우 무음 모드를 사용하고 사용자 동작이 있는 경우 (예: 사용자가 앱에서 로그인 버튼을 클릭함) 대화형 모드를 사용하는 것입니다. Google에서는 동작 요구사항을 시행하지 않습니다.

캐싱

Chrome에는 액세스 토큰의 메모리 내 캐시가 있으므로 토큰을 사용해야 할 때마다 getAuthToken를 호출할 수 있습니다. 토큰 만료는 캐시에서 자동으로 처리됩니다.

chrome://identity-internals에서 토큰 캐시의 현재 상태를 확인할 수 있습니다.

사용자가 비밀번호를 변경하는 경우와 같이 만료되지 않은 액세스 토큰이 작동하지 않는 경우가 있습니다. 토큰을 사용하는 API 호출이 HTTP 상태 코드 401과 함께 반환되기 시작합니다. 이러한 일이 감지되면 identity.removeCachedAuthToken을 호출하여 Chrome 캐시에서 잘못된 토큰을 삭제할 수 있습니다.

removeCachedAuthToken 사용 예:

// callback = function (error, httpStatus, responseText);
function authenticatedXhr(method, url, callback) {
  var retry = true;
  function getTokenAndXhr() {
    chrome.identity.getAuthToken({/* details */},
                                 function (access_token) {
      if (chrome.runtime.lastError) {
        callback(chrome.runtime.lastError);
        return;
      }

      var xhr = new XMLHttpRequest();
      xhr.open(method, url);
      xhr.setRequestHeader('Authorization',
                           'Bearer ' + access_token);

      xhr.onload = function () {
        if (this.status === 401 && retry) {
          // This status may indicate that the cached
          // access token was invalid. Retry once with
          // a fresh token.
          retry = false;
          chrome.identity.removeCachedAuthToken(
              { 'token': access_token },
              getTokenAndXhr);
          return;
        }

        callback(null, this.status, this.responseText);
      }
    });
  }
}

Google 외 계정 인증

다음 3단계를 완료해야 합니다.

  1. 제공업체에 등록합니다.
  2. 앱이 액세스할 제공업체 리소스에 대한 권한을 추가합니다.
  3. 인증 토큰을 가져옵니다.

제공업체에 등록

제공업체에 OAuth2 클라이언트 ID를 등록하고 클라이언트 ID를 웹사이트로 구성해야 합니다. 등록 중에 입력할 리디렉션 URI의 경우 https://<extension-id>.chromiumapp.org/<anything-here> 형식의 URL을 사용합니다.

예를 들어 앱 ID가 abcdefghijklmnopqrstuvwxyzabcdef이고 provider_cb를 경로로 지정하여 다른 제공업체의 리디렉션 URI와 구별하려면 다음을 사용해야 합니다. https://abcdefghijklmnopqrstuvwxyzabcdef.chromiumapp.org/provider_cb

제공업체 권한 추가

공급자 API 엔드포인트로 교차 출처 XHR을 실행하려면 권한에서 적절한 패턴을 허용 목록에 추가해야 합니다.

"permissions": [
  ...
  "https://www.website-of-provider-with-user-photos.com/photos/*"
]

토큰 가져오기

토큰을 가져오려면 다음 단계를 따르세요.

chrome.identity.launchWebAuthFlow(
  {'url': '<url-to-do-auth>', 'interactive': true},
  function(redirect_url) { /* Extract token from redirect_url */ });

<url-to-do-auth>는 웹사이트에서 제공업체에 인증하는 URL입니다. 예를 들어 제공업체와 OAuth2 흐름을 실행하고 클라이언트 ID 123456789012345로 앱을 등록했으며 제공업체 웹사이트에서 사용자의 사진에 액세스하려고 한다고 가정해 보겠습니다. https://www.website-of-provider-with-user-photos.com/dialog/oauth?client_id=123456789012345& redirect_uri=https://abcdefghijklmnopqrstuvwxyzabcdef.chromiumapp.org/provider_cb&response_type=token&scope=user_photos

공급업체는 인증을 실행하고 적절한 경우 사용자에게 로그인 또는 승인 UI를 표시합니다. 그러면 https://abcdefghijklmnopqrstuvwxyzabcdef.chromiumapp.org/provider_cb#authToken=<auth-token>로 리디렉션됩니다.

Chrome은 이를 캡처하고 전체 리디렉션 URL을 사용하여 앱의 콜백을 호출합니다. 앱은 URL에서 토큰을 추출해야 합니다.

대화형 모드와 자동 모드 비교

launchWebAuthFlow를 호출할 때 API를 대화형 모드 (자동 모드)에서 호출할지 여부를 나타내는 플래그 (위 예에서는 'interactive': true)를 전달할 수 있습니다. 대화형 모드에서 API를 호출하면 필요한 경우 토큰을 가져오기 위한 UI (로그인 UI 또는 승인 UI 또는 제공업체별 UI)가 사용자에게 표시됩니다.

무음 모드에서 API를 호출하면 제공업체가 UI를 표시하지 않고 토큰을 제공할 수 있는 경우에만 API가 토큰을 반환합니다. 이는 앱 시작 시 앱이 흐름을 실행할 때 또는 관련된 사용자 동작이 없는 일반적인 경우에 유용합니다.

권장사항은 사용자 동작이 없는 경우 무음 모드를 사용하고 사용자 동작이 있는 경우 (예: 사용자가 앱에서 로그인 버튼을 클릭함) 대화형 모드를 사용하는 것입니다. 동작 요구사항은 적용되지 않습니다.