여기에 설명된 일부 업데이트는 Google I/O 세션인 안전하고 원활한 로그인: 사용자 참여도 유지에서 설명합니다.
Chrome 57
Chrome 57에서는 Credential Management API에 이 중요한 변경사항을 도입했습니다.
다른 하위 도메인에서 사용자 인증 정보를 공유할 수 있습니다.
이제 Chrome은 Credential Management API를 사용하여 다른 하위 도메인에 저장된 사용자 인증 정보를 가져올 수 있습니다.
예를 들어 비밀번호가 login.example.com
에 저장된 경우 www.example.com
의 스크립트는 계정 선택기 대화상자의 계정 항목 중 하나로 비밀번호를 표시할 수 있습니다.
사용자가 대화상자를 탭하여 사용자 인증 정보를 선택할 때 비밀번호가 전달되고 현재 출처에 복사되도록 navigator.credentials.store()
를 사용하여 비밀번호를 명시적으로 저장해야 합니다.
비밀번호가 저장되면 정확히 동일한 출처 www.example.com
이상에서 사용자 인증 정보로 사용할 수 있습니다.
다음 스크린샷에서 login.aliexpress.com
에 저장된 사용자 인증 정보는 m.aliexpress.com
에 표시되며 사용자가 선택할 수 있습니다.
Chrome 60
Chrome 60에서는 Credential Management API에 몇 가지 중요한 변경사항이 도입되었습니다.
비밀번호를 가져오는 데 더 이상 맞춤
fetch()
함수가 필요하지 않으므로 곧 지원 중단될 예정입니다.이제
navigator.credentials.get()
는 불리언 플래그unmediated
대신 enummediation
를 허용합니다.새 메서드
navigator.credentials.create()
는 사용자 인증 정보 객체를 비동기식으로 만듭니다.
기능 감지에 주의가 필요함
비밀번호 기반 및 제휴 사용자 인증 정보에 액세스하는 Credential Management API를 사용할 수 있는지 확인하려면 window.PasswordCredential
또는 window.FederatedCredential
를 사용할 수 있는지 확인합니다.
if (window.PasswordCredential || window.FederatedCredential) {
// The Credential Management API is available
}
이제 PasswordCredential
객체에 비밀번호가 포함됨
Credential Management API는 비밀번호 처리에 보수적인 접근 방식을 취했습니다.
JavaScript에서 비밀번호를 숨겨 개발자가 fetch()
API 확장 프로그램을 통해 유효성 검사를 위해 PasswordCredential
객체를 서버로 직접 전송해야 했습니다.
하지만 이 접근 방식에는 몇 가지 제한사항이 있습니다. 다음과 같은 이유로 개발자가 API를 사용할 수 없다는 의견이 접수되었습니다.
비밀번호를 JSON 객체의 일부로 전송해야 했습니다.
비밀번호의 해시 값을 서버로 전송해야 했습니다.
보안 분석을 수행한 결과, JavaScript에서 비밀번호를 숨겨도 모든 공격 벡터가 기대만큼 효과적으로 차단되지 않는다는 사실을 확인하여 변경하기로 결정했습니다.
이제 Credential Management API는 반환된 사용자 인증 정보 객체에 원시 비밀번호를 포함하므로 일반 텍스트로 액세스할 수 있습니다. 기존 메서드를 사용하여 사용자 인증 정보(애플리케이션 사용자 인증 정보)를 서버에 전송할 수 있습니다.
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(passwordCred => {
if (passwordCred) {
let form = new FormData();
form.append('email', passwordCred.id);
form.append('password', passwordCred.password);
form.append('csrf_token', csrf_token);
return fetch('/signin', {
method: 'POST',
credentials: 'include',
body: form
});
} else {
// Fallback to sign-in form
}
}).then(res => {
if (res.status === 200) {
return res.json();
} else {
throw 'Auth failed';
}
}).then(profile => {
console.log('Auth succeeded', profile);
});
맞춤 가져오기가 곧 지원 중단됨
맞춤 fetch()
함수를 사용 중인지 확인하려면 fetch()
함수가 credentials
속성의 값으로 PasswordCredential
객체 또는 FederatedCredential
객체를 사용하는지 확인합니다. 예를 들면 다음과 같습니다.
fetch('/signin', {
method: 'POST',
credentials: c
})
이전 코드 예와 같이 일반 fetch()
함수를 사용하거나 XMLHttpRequest
를 사용하는 것이 좋습니다.
이제 navigator.credentials.get()
에서 enum 미디에이션을 허용합니다.
Chrome 60까지 navigator.credentials.get()
는 불리언 플래그와 함께 선택적 unmediated
속성을 허용했습니다. 예를 들면 다음과 같습니다.
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
unmediated: true
}).then(c => {
// Sign-in
});
unmediated: true
를 설정하면 브라우저가 사용자 인증 정보를 전달할 때 계정 선택기를 표시하지 않습니다.
이제 플래그가 미디에이션으로 확장됩니다. 사용자 미디에이션은 다음과 같은 경우에 발생할 수 있습니다.
사용자는 로그인할 계정을 선택해야 합니다.
사용자가
navigator.credentials.requireUseMediation()
호출 후에 명시적으로 로그인하려고 합니다.
mediation
값에 다음 옵션 중 하나를 선택합니다.
mediation 값 |
부울 플래그와 비교 | 동작 | |
---|---|---|---|
silent |
unmediated: true 과(와) 같음 |
계정 선택기를 표시하지 않고 인증 정보가 전달되었습니다. | |
optional |
unmediated: false 과(와) 같음 |
이전에 preventSilentAccess() 이 호출된 경우 계정 선택 도구를 표시합니다. |
|
required |
새로운 옵션 | 계정 선택 도구를 항상 표시합니다. 사용자가 네이티브 계정 선택기 대화상자를 사용하여 계정을 전환하도록 허용하려는 경우에 유용합니다. |
이 예에서는 이전 플래그 unmediated: true
와 동일한 계정 선택 도구를 표시하지 않고 사용자 인증 정보가 전달됩니다.
navigator.credentials.get({
password: true,
federated: {
providers: [ 'https://accounts.google.com' ]
},
mediation: 'silent'
}).then(c => {
// Sign-in
});
requireUserMediation()
에서 preventSilentAccess()
로 이름이 변경되었습니다.
get()
호출에서 제공되는 새 mediation
속성과 잘 일치하도록 navigator.credentials.requireUserMediation()
메서드의 이름이 navigator.credentials.preventSilentAccess()
로 변경되었습니다.
이름이 변경된 메서드는 계정 선택 도구를 표시하지 않고 사용자 인증 정보를 전달하지 못하도록 합니다(사용자 미디에이션 없이 호출이라고도 함). 이는 사용자가 웹사이트에서 로그아웃하거나 등록을 해제한 후 다음에 방문할 때 자동으로 다시 로그인되지 않도록 하는 데 유용합니다.
signoutUser();
if (navigator.credentials) {
navigator.credentials.preventSilentAccess();
}
새 메서드 navigator.credentials.create()
를 사용하여 사용자 인증 정보 객체를 비동기식으로 만듭니다.
이제 새 메서드 navigator.credentials.create()
를 사용하여 사용자 인증 정보 객체를 비동기식으로 만들 수 있습니다.
동기식 접근 방식과 비동기식 접근 방식을 비교해 보세요.
PasswordCredential
객체 만들기
동기화 접근 방식
let c = new PasswordCredential(form);
비동기 접근 방식 (신규)
let c = await navigator.credentials.create({
password: form
});
또는:
let c = await navigator.credentials.create({
password: {
id: id,
password: password
}
});
FederatedCredential
객체 만들기
동기화 접근 방식
let c = new FederatedCredential({
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
});
비동기 접근 방식 (신규)
let c = await navigator.credentials.create({
federated: {
id: 'agektmr',
name: 'Eiji Kitamura',
provider: 'https://accounts.google.com',
iconURL: 'https://*****'
}
});
이전 가이드
Credential Management API의 기존 구현이 있나요? 새 버전으로 업그레이드하는 방법은 이전 가이드 문서를 참고하세요.