Amazon Cognito 사용자 풀에서 기억된 디바이스를 사용하려면 어떻게 해야 합니까?

최종 업데이트 날짜: 2020년 1월 8일

Amazon Cognito 사용자 풀의 사용자가 앱에 로그인하는 데 사용한 디바이스를 추적하려고 합니다. 어떻게 해야 합니까?

간략한 설명

Amazon Cognito는 사용자 풀의 사용자가 로그인에 사용하는 디바이스를 추적하고 기억할 수 있습니다. 디바이스 기억을 활성화하여 로그인 제한을 설정할 수 있습니다(예: 단일 디바이스에서의 로그인 제한). 또는 사용자가 동일한 디바이스에서 반복 로그인을 건너뛰도록 할 수 있습니다. 자세한 내용은 사용자 풀 디바이스 추적 설정 지정을 참조하십시오.

참고: 기억된 디바이스 기능은 USER_SRP_AUTH 인증 흐름에서만 작동합니다. 또한 이 기능을 사용하려면 사용자 풀에 멀티 팩터 인증(MFA)을 활성화해야 합니다.

디바이스 기억은 두 부분으로 구성된 프로세스입니다.

  • 새 디바이스 확인. 디바이스에서 인증을 시작한 다음 Amazon Cognito에서 이를 확인하여 고유한 디바이스 식별자를 얻습니다.
  • 확인된 디바이스 인증. 확인된 디바이스에서 인증을 시작하여 후속 로그인 시도에서 MFA 단계를 건너뜁니다.

해결 방법

참고: 다음 지침에서는 일반적으로 앱 클라이언트의 코드에서 수행할 Amazon Cognito API 호출을 설명합니다. Android 또는 iOS용 AWS Mobile SDK와 같은 클라이언트 측 SDK를 사용하는 경우 구현 대부분이 SDK에서 처리됩니다.

기억된 디바이스 설정

  1. Amazon Cognito 콘솔에서 [사용자 풀 관리]를 선택한 다음, 사용자 풀을 선택합니다.
  2. 왼쪽 탐색 창의 [일반 설정]에서 [디바이스]를 선택합니다.
  3. [사용자 디바이스를 기억하시겠습니까?]에서 [항상] 또는 [사용자 옵트인]을 선택합니다. 자세한 내용은 Tracking and Remembering Devices Using Amazon Cognito Your User Pools를 참조하십시오.
  4. [멀티 팩터 인증(MFA) 중에 기억한 디바이스를 이용해 두 번째 요소를 억제하시겠습니까?]에서 [] 또는 [아니요]를 선택합니다. 자세한 내용은 기억된 디바이스를 사용하여 MFA(멀티 팩터 인증) 억제를 참조하십시오.
    참고: 이러한 옵션이 표시되지 않으면 MFA가 활성화되지 않은 것입니다. MFA를 설정하려면 왼쪽 탐색 창에서 MFA 및 확인을 선택합니다.
  5. [변경 내용 저장]을 선택합니다.

자세한 내용은 사용자 풀 디바이스 추적 설정 지정을 참조하십시오.

SetUserMFAPreference 호출

앱 클라이언트의 코드에서 SetUserMFAPreference API를 호출하여 사용 중인 MFA 메서드에 대해 MFA 기본 설정을 [true]로 설정합니다.

InitiateAuth 호출

앱 클라이언트의 코드에서 InitiateAuth API를 호출하여 디바이스 키를 가져옵니다. 이 API 요청에는 다음 요청 파라미터를 포함해야 합니다.

  • AuthFlow. USER_SRP_AUTH를 사용합니다.
  • AuthParameters. 인증 파라미터 USERNAME, SRP_ASECRET_HASH를 포함시킵니다.
    참고: SECRET_HASH는 앱 클라이언트에 클라이언트 보안 암호가 구성된 경우에만 필요합니다.

다음 공식을 사용하여 SRP_A를 계산합니다.

SRP_A = ga (mod N)

  • AWS Amplify(JavaScript) GitHub 리포지토리의 AuthenticationHelper.js에 정의된 대로 g를 사용합니다.
  • a = 128 랜덤 바이트로 유지합니다.

자세한 내용은 Request Syntax선택한 AWS SDK에 대한 API 참조를 참조하십시오.

MFA 문제를 위한 RespondToAuthChallenge 호출

앱 클라이언트가 InitiateAuth API를 호출하면 Amazon Cognito 사용자 풀에서 사용자가 활성화한 MFA 방식을 기반으로 일련의 MFA 문제를 반환합니다.

앱은 RespondToAuthChallenge API를 사용하여 이러한 문제에 답해야 합니다. 예를 들어 사용자 풀에서 [SMS 문자 메시지] MFA를 활성화한 경우 SMS_MFA 값을 가진 파라미터 ChallengeName을 포함시킵니다. 자세한 내용은 Request Syntax선택한 AWS SDK에 대한 API 참조를 참조하십시오.

디바이스 키 저장

모든 MFA 문제에 응답하면 Amazon Cognito는 NewDeviceMetadataType 필드에 DeviceGroupKey와 고유한 DeviceKey로 응답합니다.

브라우저에서 Android, iOS 또는 JavaScript용 AWS Mobile SDK를 사용하는 경우, 자동으로 애플리케이션에서 이러한 키를 디바이스의 로컬 스토리지로 이동합니다. 다른 AWS SDK를 사용하는 경우, 앱에 대해 유사한 키 스토리지 솔루션을 설계해야 합니다.

ConfirmDevice 호출

DeviceGroupKeyDeviceKey와 함께 SRP(Secure Remote Password) 프로토콜을 사용하여 보안 암호를 생성합니다. 이렇게 하면 솔트 및 암호 확인자가 생성됩니다. 이 정보를 다음과 같은 요청 파라미터를 포함하는 ConfirmDevice API 호출을 통해 Amazon Cognito에 전달합니다.

  • AccessToken. 사용자에 대해 유효한 액세스 토큰을 사용합니다.
  • DeviceKey. Amazon Cognito에서 반환된 디바이스의 고유 키를 사용합니다.
  • DeviceName. 디바이스에 지정할 이름을 사용합니다. (AWS Mobile SDK는 User Agent를 사용합니다.)
  • DeviceSecretVerifierConfig. Salt(16 랜덤 바이트, base64 인코딩) 및 PasswordVerifier를 포함시킵니다.

PasswordVerifier에는 다음 공식을 사용합니다.

PasswordVerifier = g(salt + FULL_PASSWORD) (mod N)

  • AWS Amplify(JavaScript) GitHub 리포지토리의 AuthenticationHelper.js에 정의된 대로 g를 사용합니다.
  • FULL_PASSWORD = SHA256_HASH(DeviceGroupKey+username+":"+RANDOM_PASSWORD)로 유지합니다.
  • RANDOM_PASSWORD = 40 랜덤 바이트, base64 인코딩으로 유지합니다.
  • AWS Amplify(JavaScript) GitHub 리포지토리의 AuthenticationHelper.js에 정의된 대로 N을 사용합니다.

자세한 내용은 Request Syntax선택한 AWS SDK에 대한 API 참조를 참조하십시오.

(선택 사항) UpdateDeviceStatus 호출

사용자 풀에서 기억된 디바이스를 설정할 때 [항상]을 선택한 경우, 이 단계를 건너뛸 수 있습니다. [사용자 옵트인]을 선택한 경우, UpdateDeviceStatus API 호출을 포함해야 합니다.

참고: JavaScript용 Amazon Cognito Identity SDK를 사용하는 경우 setDeviceStatusRemembered 또는 setDeviceStatusNotRemembered 호출을 설치해야 합니다. 자세한 내용은 GitHub에 있는 SDK의 README 파일에서 Usage를 참조하십시오.

앱 사용자에게 디바이스를 기억할 수 있는 옵션을 제공할 때 디바이스를 확인하면 사용자 풀에서 '기억되지 않음'으로 추적됩니다. 사용자에게 기억할지 여부를 물은 다음, 사용자의 입력을 UpdateDeviceStatus API를 사용하여 전송해야 합니다.

참고: 옵트인이 필요한 경우 사용자가 옵트인해야 디바이스를 기억하고 MFA 문제를 억제할 수 있습니다.

디바이스 키를 사용한 InitiateAuth 호출

앱 클라이언트의 코드에서 InitiateAuth API를 호출하여 기억된 디바이스를 확인합니다. 이 호출에는 다음과 같이 요청 파라미터에 디바이스 키를 포함시킵니다.

  • AuthFlow. USER_SRP_AUTH를 사용합니다.
  • AuthParameters. 인증 파라미터 USERNAME, SRP_ADEVICE_KEY를 포함시킵니다.

자세한 내용은 Request Syntax선택한 AWS SDK에 대한 API 참조를 참조하십시오.

DEVICE_SRP_AUTH에 대한 RespondToAuthChallenge 호출

앱 클라이언트가 유효한 디바이스 키로 InitiateAuth API를 호출하면 Amazon Cognito 사용자 풀에서 DEVICE_SRP_AUTH 문제를 반환합니다. 응답하려면 RespondToAuthChallenge API를 호출하고 다음 요청 파라미터를 포함시킵니다.

  • ChallengeName. DEVICE_SRP_AUTH를 사용합니다.
  • ClientId. 유효한 앱 클라이언트 ID를 사용합니다.
  • ChallengeResponses. 이러한 응답에 USERNAME, DEVICE_KEYSRP_A를 포함시킵니다.
    참고: SRP_A의 경우, 이 지침 앞부분에서 언급한 공식을 사용하십시오.

이 API 호출 후 Amazon Cognito는 DEVICE_PASSWORD_VERIFIER라는 또 하나의 문제에 응답합니다. 이 응답에서 문제에 응답하는 데 필요한 ChallengeParameters SECRET_BLOCKSRP_B의 값도 얻게 됩니다.

자세한 내용은 Request Syntax선택한 AWS SDK에 대한 API 참조를 참조하십시오.

DEVICE_PASSWORD_VERIFIER에 대한 RespondToAuthChallenge 호출

DEVICE_PASSWORD_VERIFIER 문제에 응답하려면 RespondToAuthChallenge API를 호출하고 다음과 같은 요청 파라미터를 포함시킵니다.

  • ChallengeName. DEVICE_PASSWORD_VERIFIER를 사용합니다.
  • ClientId. 유효한 앱 클라이언트 ID를 사용합니다.
  • ChallengeResponses. USERNAME, PASSWORD_CLAIM_SECRET_BLOCK, TIMESTAMP, PASSWORD_CLAIM_SIGNATUREDEVICE_KEY를 포함시킵니다.

문제 응답을 다음과 같이 정의합니다.

  • PASSWORD_CLAIM_SECRET_BLOCK의 경우, SECRET_BLOCK의 값을 사용합니다.
  • TIMESTAMP의 경우, 현재 시간을 포함시킵니다. (예: Tue Sep 25 00:09:40 UTC 2018)
  • PASSWORD_CLAIM_SIGNATURE = SHA256_HMAC(K_USER, DeviceGroupKey + DeviceKey + PASSWORD_CLAIM_SECRET_BLOCK + TIMESTAMP), base64 인코딩으로 유지합니다.
  • K_USER = SHA256_HASH(S_USER)로 유지합니다.
  • S_USER = (SRP_B - k * gx)(a + ux)로 유지합니다.
  • x = SHA256_HASH(salt + FULL_PASSWORD)로 유지합니다.
  • u = SHA256_HASH(SRP_A + SRP_B)로 유지합니다.
  • k = SHA256_HASH(N+g)로 유지합니다.

사용자 풀에서 JSON 웹 토큰 가져오기

마지막 문제에 성공적으로 응답한 후 Amazon Cognito 사용자 풀은 AuthenticationResult에 JSON 웹 토큰을 반환합니다.

{ 
    "AuthenticationResult": { 
        "AccessToken": "...", 
        "ExpiresIn": 3600, 
        "IdToken": "...", 
        "RefreshToken": "...", 
        "TokenType": "Bearer" 
    }, 
    "ChallengeParameters": {} 
}

사용자 풀 인증 흐름

사용자 풀 참조(AWS Management Console)

AuthenticationHelper.js(AWS Amplify GitHub 리포지토리)

CognitoUser.js(AWS Amplify GitHub 리포지토리)

이 문서가 도움이 되었습니까?

AWS에서 개선해야 할 부분이 있습니까?


도움이 필요하십니까?