사용자 인증

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

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

사용 방법

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

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

Google 계정 인증

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

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

권한 추가 및 앱 업로드

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

"permissions": [
  "identity"
]

매니페스트에 키 복사

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

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

  1. 사용자 데이터 디렉터리로 이동합니다. MacO의 예: ~/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 API 콘솔에 로그인합니다.
  2. 왼쪽 상단의 드롭다운 메뉴를 펼치고 Create... 메뉴 항목을 선택하여 새 프로젝트를 만듭니다.
  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 이외의 계정 인증

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

  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를 호출하면 API는 제공업체가 UI를 표시하지 않고 토큰을 제공할 수 있는 경우에만 토큰을 반환합니다. 이는 앱이 앱 시작 시 흐름을 실행하는 경우나 일반적으로 사용자 동작이 관련되지 않은 경우에 유용합니다.

관련된 사용자 동작이 없을 때는 무음 모드를 사용하고 사용자 동작이 있는 경우 (예: 사용자가 앱에서 로그인 버튼을 클릭함) 대화형 모드를 사용하는 것이 좋습니다. Google에서는 동작 요구사항을 강제하지 않습니다.