AWS Severless IoT 3 – Cognito User Pool

AWS Severless IoT에 대해 알아봅니다.

작성자

홍세민

홍세민

MarcusHong

Cognito User Pool

서비스를 개발하려면 먼저 사용자 인증이 필요하다. Cognito를 사용하면 사용자 인증 작업이 생략됨과 동시에 aws의 보안시스템을 사용하게 되므로 개발초기의 작업량이 상당히 줄어든다. 또한 API Gateway와 Iot를 쓴다면 Cognito로 인증을 하겠다는 옵션을 설정하게 되면 Cognito에서 Lambda로 실행하기 전에 인증을 처리하므로 편리하다. 가입 및 로그인 역시 모바일에서 처리할 수 있으므로, 쓰게 되면 많은 이점이 있다.

Cloudformation

AWSTemplateFormatVersion: '2010-09-09'
Description: Dev Master Stack

Parameters:
  Environment:
    Default: Dev
    Type: String

Resources:
  CognitoAuthorizedRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action:
          - sts:AssumeRoleWithWebIdentity
          Condition:
            ForAnyValue:StringLike:
              cognito-identity.amazonaws.com:amr: authenticated
            StringEquals:
              cognito-identity.amazonaws.com:aud:
                Ref: CognitoIdentityPool
          Effect: Allow
          Principal:
            Federated: cognito-identity.amazonaws.com
        Version: '2012-10-17'
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - mobileanalytics:PutEvents
            - cognito-sync:*
            - cognito-identity:*
            - iot:*
            Effect: Allow
            Resource: '*'
          Version: '2012-10-17'
        PolicyName: CognitoAuthorizedPolicy
    Type: AWS::IAM::Role

  CognitoExecutionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action: sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
            - apigateway.amazonaws.com
        Version: '2012-10-17'
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - cognito-idp:*
            - dynamodb:*
            - lambda:InvokeFunction
            Effect: Allow
            Resource: '*'
          Version: '2012-10-17'
        PolicyName: LambdaCognitoPolicy
    Type: AWS::IAM::Role

  CognitoIdentityPool:
    Properties:
      AllowUnauthenticatedIdentities: false
      CognitoIdentityProviders:
      - ClientId:
          Ref: CognitoUserPoolAppClient
        ProviderName:
          Fn::GetAtt:
          - CognitoUserPool
          - ProviderName
      - ClientId:
          Ref: CognitoUserPoolWebClient
        ProviderName:
          Fn::GetAtt:
          - CognitoUserPool
          - ProviderName
      IdentityPoolName:
        Fn::Sub: ${Environment}IdentityPool
    Type: AWS::Cognito::IdentityPool



  CognitoUnAuthorizedRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action:
          - sts:AssumeRoleWithWebIdentity
          Condition:
            ForAnyValue:StringLike:
              cognito-identity.amazonaws.com:amr: unauthenticated
            StringEquals:
              cognito-identity.amazonaws.com:aud:
                Ref: CognitoIdentityPool
          Effect: Allow
          Principal:
            Federated: cognito-identity.amazonaws.com
        Version: '2012-10-17'
      Policies:
      - PolicyDocument:
          Statement:
          - Action:
            - mobileanalytics:PutEvents
            Effect: Allow
            Resource: '*'
          Version: '2012-10-17'
        PolicyName: CognitoUnauthorizedPolicy
    Type: AWS::IAM::Role

  CognitoUserPool:
    Properties:
      AdminCreateUserConfig:
        AllowAdminCreateUserOnly: false
      AutoVerifiedAttributes:
      - email
      DeviceConfiguration:
        ChallengeRequiredOnNewDevice: true
      LambdaConfig:
        PreSignUp:
          Fn::GetAtt:
          - CognitoPreSignUp
          - Arn
      Policies:
        PasswordPolicy:
          MinimumLength: 6
          RequireLowercase: false
          RequireNumbers: false
          RequireSymbols: false
          RequireUppercase: false
      Schema:
      - AttributeDataType: String
        DeveloperOnlyAttribute: false
        Mutable: false
        Name: email
        Required: true
        StringAttributeConstraints:
          MaxLength: '255'
          MinLength: '5'
      UserPoolName:
        Fn::Sub: ${Environment}UserPool
    Type: AWS::Cognito::UserPool

  CognitoUserPoolAppClient:
    Properties:
      ClientName:
        Fn::Sub: ${Environment}App
      GenerateSecret: true
      RefreshTokenValidity: 365
      UserPoolId:
        Ref: CognitoUserPool
    Type: AWS::Cognito::UserPoolClient

  CognitoUserPoolWebClient:
    Properties:
      ClientName:
        Fn::Sub: ${Environment}Web
      GenerateSecret: false
      RefreshTokenValidity: 365
      UserPoolId:
        Ref: CognitoUserPool
    Type: AWS::Cognito::UserPoolClient

Outputs:
  UserPoolAppClient:
    Value:
      Ref: CognitoUserPoolAppClient
  UserPoolId:
    Value:
      Ref: CognitoUserPool
  UserPoolWebClient:
    Value:
      Ref: CognitoUserPoolWebClient

환경변수

Environment를 선언해서 스택을 생성할 때 리소스의 이름을 다르게 만들어 개발/운영 서버를 구분할 수 있게 함. 구분할 필요가 없다면 고정값으로 바꾸어도 무방하다.

refresh token

Cognito는 jwt로 토큰을 생성하며, access token, refresh token을 사용하는 Oauth 방식이다. RefreshTokenValidity 에서 refresh token의 유효기간을 정할 수 있다.

인증

CognitoUserPool에서 유저 패스워드 정책, 이메일이나 전화번호 인증을 필수로 선택하게 할 수도 있다.

Client 설정

CognitoUserPoolAppClient, CognitoUserPoolWebClient 을 선언해서 앱과, 백엔드에서 Cognito를 사용할 수 있게 한다. 이 때, javascript는 secret을 만들 수가 없어, GenerateSecret: true 로 하게 되면 오류가 발생한다.

Tags : aws 

comments powered by Disqus