사용자 인증 정보 관리 API를 사용한 로그인 흐름 간소화

정교한 사용자 환경을 제공하려면 사용자가 웹사이트에 자신을 인증하도록 지원하는 것이 중요합니다. 인증된 사용자는 전용 프로필을 사용하여 서로 상호작용하거나, 기기 간에 데이터를 동기화하거나, 오프라인 상태에서 데이터를 처리할 수 있습니다. 이 목록은 계속 반복됩니다. 하지만 비밀번호를 만들고 기억하고 입력하는 것은 최종 사용자가 번거롭게 느껴질 수 있으며, 특히 휴대기기 화면에서는 여러 사이트에서 같은 비밀번호를 재사용하게 되어 더욱 번거롭습니다. 이것은 물론 보안 위험입니다.

최신 버전의 Chrome (51)은 Credential Management API를 지원합니다. 이는 W3C의 표준 트랙 제안으로, 개발자가 브라우저의 인증 관리자에 프로그래매틱 방식으로 액세스할 수 있도록 해주고 사용자가 더 쉽게 로그인할 수 있도록 도와줍니다.

Credential Management API란 무엇인가요?

Credential Management API는 개발자가 비밀번호 사용자 인증 정보와 제휴 사용자 인증 정보를 저장하고 검색할 수 있게 해 주며 다음과 같은 3가지 기능을 제공합니다.

  • navigator.credentials.get()
  • navigator.credentials.store()
  • navigator.credentials.requireUserMediation()

개발자는 이러한 간단한 API를 사용하여 다음과 같은 강력한 작업을 수행할 수 있습니다.

  • 사용자가 탭 한 번으로 로그인할 수 있도록 지원하세요.
  • 사용자가 로그인할 때 사용한 제휴 계정을 기억합니다.
  • 세션이 만료되면 사용자를 다시 로그인 처리합니다.

Chrome 구현 시 사용자 인증 정보는 Chrome의 비밀번호 관리자에 저장됩니다. 사용자가 Chrome에 로그인하면 기기 간에 사용자의 비밀번호를 동기화할 수 있습니다. 동기화된 비밀번호는 원활한 크로스 플랫폼 환경을 위해 Android용 Smart Lock for Passwords API를 통합한 Android 앱과도 공유할 수 있습니다.

Credential Management API를 사이트와 통합

웹사이트에서 Credential Management API를 사용하는 방법은 아키텍처에 따라 다를 수 있습니다. 단일 페이지 앱인가요? 페이지 전환이 있는 기존 아키텍처인가요? 로그인 양식이 페이지 상단에만 있나요? 로그인 버튼이 모든 곳에 있나요? 사용자가 로그인하지 않고 웹사이트를 의미 있게 탐색할 수 있나요? 제휴가 팝업 창 내에서 작동하나요? 아니면 여러 페이지에서의 상호작용이 필요한가요?

이러한 모든 사례를 다루는 것은 거의 불가능하지만 일반적인 단일 페이지 앱을 살펴보겠습니다.

  • 맨 위 페이지에는 등록 양식이 있습니다.
  • 사용자가 '로그인' 버튼을 탭하면 로그인 양식으로 이동합니다.
  • 등록 양식과 로그인 양식 모두에 ID/비밀번호 사용자 인증 정보 및 제휴(예: Google 로그인 및 Facebook 로그인)에 대한 일반적인 옵션이 있습니다.

Credential Management API를 사용하여 사이트에 다음 기능을 추가할 수 있습니다. 예를 들면 다음과 같습니다.

  • 로그인 시 계정 선택기 표시: 사용자가 '로그인'을 탭하면 기본 계정 선택기 UI를 표시합니다.
  • 사용자 인증 정보 저장: 로그인이 성공되면 나중에 사용할 수 있도록 사용자 인증 정보를 브라우저의 비밀번호 관리자에 저장하도록 제안합니다.
  • 사용자가 자동으로 다시 로그인하도록 허용: 세션이 만료되면 사용자가 다시 로그인하도록 허용합니다.
  • 자동 로그인 미디에이션: 사용자가 로그아웃한 후 사용자의 다음 방문 시 자동 로그인을 사용 중지합니다.

데모 사이트에서 샘플 코드를 통해 이러한 기능을 사용해 볼 수 있습니다.

로그인 시 계정 선택기 표시

사용자가 '로그인' 버튼을 탭하고 로그인 양식으로 이동하는 사이에 navigator.credentials.get()을 사용하여 사용자 인증 정보를 가져올 수 있습니다. Chrome에 사용자가 계정을 선택할 수 있는 계정 선택기 UI가 표시됩니다.

사용자가 로그인할 계정을 선택할 수 있는 계정 선택기 UI가 표시됩니다.
사용자가 로그인할 계정을 선택할 수 있는 계정 선택기 UI가 표시됨

비밀번호 사용자 인증 정보 객체 가져오기

계정 옵션으로 비밀번호 사용자 인증 정보를 표시하려면 password: true를 사용합니다.

navigator.credentials.get({
    password: true, // `true` to obtain password credentials
}).then(function(cred) {
    // continuation
    ...

비밀번호 사용자 인증 정보를 사용하여 로그인

사용자가 계정을 선택하면 확인 기능이 비밀번호 사용자 인증 정보를 수신합니다. fetch()를 사용하여 서버로 전송할 수 있습니다.

    // continued from previous example
}).then(function(cred) {
    if (cred) {
    if (cred.type == 'password') {
        // Construct FormData object
        var form = new FormData();

        // Append CSRF Token
        var csrf_token = document.querySelector('csrf_token').value;
        form.append('csrf_token', csrf_token);

        // You can append additional credential data to `.additionalData`
        cred.additionalData = form;

        // `POST` the credential object as `credentials`.
        // id, password and the additional data will be encoded and
        // sent to the url as the HTTP body.
        fetch(url, {           // Make sure the URL is HTTPS
        method: 'POST',      // Use POST
        credentials: cred    // Add the password credential object
        }).then(function() {
        // continuation
        });
    } else if (cred.type == 'federated') {
        // continuation

제휴 사용자 인증 정보를 사용하여 로그인

제휴 계정을 사용자에게 표시하려면 ID 공급업체 배열을 사용하는 federatedget() 옵션에 추가합니다.

비밀번호 관리자에 여러 계정이 저장된 경우
비밀번호 관리자에 여러 계정이 저장된 경우
navigator.credentials.get({
    password: true, // `true` to obtain password credentials
    federated: {
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    }
}).then(function(cred) {
    // continuation
    ...

사용자 인증 정보 객체의 type 속성을 검사하여 PasswordCredential(type == 'password') 또는 FederatedCredential (type == 'federated')인지 확인할 수 있습니다. 사용자 인증 정보가 FederatedCredential인 경우 포함된 정보를 사용하여 적절한 API를 호출할 수 있습니다.

    });
} else if (cred.type == 'federated') {
    // `provider` contains the identity provider string
    switch (cred.provider) {
    case 'https://accounts.google.com':
        // Federated login using Google Sign-In
        var auth2 = gapi.auth2.getAuthInstance();

        // In Google Sign-In library, you can specify an account.
        // Attempt to sign in with by using `login_hint`.
        return auth2.signIn({
        login_hint: cred.id || ''
        }).then(function(profile) {
        // continuation
        });
        break;

    case 'https://www.facebook.com':
        // Federated login using Facebook Login
        // continuation
        break;

    default:
        // show form
        break;
    }
}
// if the credential is `undefined`
} else {
// show form
사용자 인증 정보 관리 흐름 차트

사용자 인증 정보 저장

사용자가 양식을 사용하여 웹사이트에 로그인하면 navigator.credentials.store()를 사용하여 사용자 인증 정보를 저장할 수 있습니다. 사용자에게 파일을 저장할지 묻는 메시지가 표시됩니다. 사용자 인증 정보 유형에 따라 new PasswordCredential() 또는 new FederatedCredential()를 사용하여 저장하려는 사용자 인증 정보 객체를 만듭니다.

Chrome에서 사용자에게 사용자 인증 정보 (또는 제휴 제공업체)를 저장할지 묻습니다.
Chrome에서 사용자에게 사용자 인증 정보 (또는 제휴 제공업체)를 저장할지 묻습니다.

양식 요소에서 비밀번호 사용자 인증 정보 만들기 및 저장

다음 코드에서는 autocomplete 속성을 사용하여 양식의 요소를 PasswordCredential 객체 매개변수에 자동으로 매핑합니다.

HTML html <form id="form" method="post"> <input type="text" name="id" autocomplete="username" /> <input type="password" name="password" autocomplete="current-password" /> <input type="hidden" name="csrf_token" value="******" /> </form>

JavaScript

var form = document.querySelector('\#form');
var cred = new PasswordCredential(form);
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});

제휴 사용자 인증 정보 만들기 및 저장

// After a federation, create a FederatedCredential object using
// information you have obtained
var cred = new FederatedCredential({
    id: id,                                  // The id for the user
    name: name,                              // Optional user name
    provider: 'https://accounts.google.com',  // A string that represents the identity provider
    iconURL: iconUrl                         // Optional user avatar image url
});
// Store it
navigator.credentials.store(cred)
.then(function() {
    // continuation
});
로그인 흐름 다이어그램

사용자가 자동으로 다시 로그인하도록 허용

사용자가 웹사이트를 떠났다가 나중에 다시 돌아올 때 세션이 만료되었을 수 있습니다. 사용자가 돌아올 때마다 비밀번호를 입력하지 않도록 하세요. 사용자가 자동으로 다시 로그인하도록 허용합니다.

사용자가 자동으로 로그인되면 알림이 표시됩니다.
사용자가 자동으로 로그인되면 알림이 표시됩니다.

사용자 인증 정보 객체 가져오기

navigator.credentials.get({
    password: true, // Obtain password credentials or not
    federated: {    // Obtain federation credentials or not
    providers: [  // Specify an array of IdP strings
        'https://accounts.google.com',
        'https://www.facebook.com'
    ]
    },
    unmediated: true // `unmediated: true` lets the user automatically sign in
}).then(function(cred) {
    if (cred) {
    // auto sign-in possible
    ...
    } else {
    // auto sign-in not possible
    ...
    }
});

코드는 '로그인 시 계정 선택기 표시' 섹션에 표시된 것과 비슷해야 합니다. 유일한 차이점은 unmediated: true를 설정한다는 것입니다.

그러면 함수가 즉시 확인되고 사용자가 자동으로 로그인할 수 있는 사용자 인증 정보가 제공됩니다. 몇 가지 조건이 있습니다.

  • 사용자가 웜 환영으로 자동 로그인 기능을 확인했습니다.
  • 사용자가 이전에 Credential Management API를 사용하여 웹사이트에 로그인한 적이 있습니다.
  • 사용자의 출처에 대해 저장된 사용자 인증 정보가 하나만 있습니다.
  • 사용자가 이전 세션에서 명시적으로 로그아웃하지 않았습니다.

이러한 조건 중 하나라도 충족되지 않으면 함수가 거부됩니다.

사용자 인증 정보 객체 흐름 다이어그램

자동 로그인 미디에이션

사용자가 웹사이트에서 로그아웃할 때 사용자가 자동으로 다시 로그인되지 않도록 하는 것은 개발자의 책임입니다. 이를 위해 Credential Management API는 중재라는 메커니즘을 제공합니다. navigator.credentials.requireUserMediation()를 호출하여 미디에이션 모드를 사용 설정할 수 있습니다. 출처에 대한 사용자의 미디에이션 상태가 사용 설정되어 있으면 unmediated: truenavigator.credentials.get()와 함께 사용하면 이 함수는 undefined로 확인됩니다.

자동 로그인 미디에이션

navigator.credentials.requireUserMediation();
자동 로그인 흐름 차트

FAQ

웹사이트의 JavaScript가 원시 비밀번호를 가져올 수 있나요? 아니요. 비밀번호는 PasswordCredential의 일부로만 가져올 수 있으며 어떤 방법으로도 노출될 수 없습니다.

Credential Management API를 사용하여 ID의 3자리 숫자 세트를 저장할 수 있나요? 현재는 그렇게 할 수 없습니다. 사양에 관한 의견을 보내주시기 바랍니다.

iframe 내에서 Credential Management API를 사용할 수 있나요? API는 최상위 컨텍스트로 제한됩니다. iframe에서 .get() 또는 .store()를 호출하면 아무런 영향을 미치지 않고 즉시 확인됩니다.

비밀번호 관리 Chrome 확장 프로그램을 Credential Management API와 통합할 수 있나요? navigator.credentials를 재정의하여 Chrome 확장 프로그램에 연결하여 get() 또는 store() 사용자 인증 정보에 연결할 수 있습니다.

자료

Credential Management API에 대한 자세한 내용은 통합 가이드를 참고하세요.