首页 文章

具有服务器端身份验证和Cognito的无服务器框架

提问于
浏览
3

我已经使用带APIG的无服务器框架,DynamoDB作为数据存储实现了各种REST-API,使用Angular2作为前端进行用户身份验证的Cognito . 服务器端的Cognito授权人可以轻松保护这些功能 . 缺点是我必须在我的前端应用程序中集成AWS SDK才能首先使用Cognito对用户进行身份验证(注册/登录,...) . 我也可以使用AWS_IAM授权程序,但在将请求发送到API网关之前,我还必须使用AWS specific signature在客户端签署所有请求 .

现在我想知道是否有可能在服务器端保留身份验证和授权,所以我可以使用像JSON Web Tokens这样的开放标准进行注册/登录?这将允许我为其他开发人员打开我的REST-API以及 without forcing them to use Cognito .

我知道一种可能性是为我的lambda函数实现一个自定义授权器,但是没有任何稳定的东西,可以用"out-of-the-box"吗?我发现的大多数示例都是在客户端使用Cognito或IAM auth AWS签名(例如serverless-stack.com) .

很遗憾到目前为止我在网上找不到任何有用的信息,因为我认为这是REST API的典型用例 . 或者我对API Gateway Cognito有一个概念上的误解?

3 回答

  • 2

    我在理解AWS Cognito的工作方式以及可用于实现身份验证和授权的选项方面遇到了同样的麻烦 . 不幸的是,没有 out-of-the-box 方法可以满足您的要求 . 尽管如此,我们希望亚马逊能够尽快推出一项功能 .

    基本上,有3个选项可用于实现身份验证 .

    • AWS_IAM

    • Cognito授权人

    • 自定义授权程序

    AWS_IAM

    除了身份验证之外,此方法还可用于轻松地使用IAM角色或IAM用户实现授权 . 唯一的缺点是你需要发送一个用 aws-signature-4 签名的请求,这不是我们在Auth0等IDP服务中看到的标准方式 .

    Cognito授权人

    此方法满足发送带有API请求的JWT令牌的期望 . 您可以在Cognito User Pool中创建用户,然后使用它来进行身份验证并生成IdToken . 但是,此方法仅允许您对用户进行身份验证;授权需要在方法级别处理 .

    自定义授权程序

    此方法可用于编写自己的身份验证和授权方式 . 此外,它有助于消除API方法中的写入授权逻辑 . 理想的解决方案是使用AWS Cognito用户池对用户进行身份验证,然后为IAM角色生成策略文档以访问资源 . 这是一个例子AWS cognito userpools JavaScript SDK get user's policy documents . 还要记住,此解决方案将为您所做的每个请求调用额外的lambda函数 .

  • 1

    您可以将Cognito Auth用于服务器端 . 以下是步骤 .

    实施注册和登录

    • 使用Lambda接收注册数据,在前端和API网关 endpoints (例如/ register)中实施注册表单,注册数据将使用AWS SDK在Cognito中创建用户 . 有关详细参考,请查看this链接 .
    AWSCognito.config.region = 'us-east-1'; //This is required to derive the endpoint
    
    var poolData = { UserPoolId : 'us-east-1_TcoKGbf7n',
        ClientId : '4pe2usejqcdmhi0a25jp4b5sh3'
    };
    var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
    
    var attributeList = [];
    
    var dataEmail = {
        Name : 'email',
        Value : 'email@mydomain.com'
    };
    var dataPhoneNumber = {
        Name : 'phone_number',
        Value : '+15555555555'
    };
    var attributeEmail = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute(dataEmail);
    var attributePhoneNumber = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute(dataPhoneNumber);
    
    attributeList.push(attributeEmail);
    attributeList.push(attributePhoneNumber);
    
    userPool.signUp('username', 'password', attributeList, null, function(err, result){
        if (err) {
            alert(err);
            return;
        }
        cognitoUser = result.user;
        console.log('user name is ' + cognitoUser.getUsername());
    });
    
    • 通过创建前端和API网关 endpoints (例如/ login)为登录做类似的操作
    var authenticationData = {
        Username : 'username',
        Password : 'password'
    };
    var authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);
    var poolData = { UserPoolId : 'us-east-1_TcoKGbf7n',
        ClientId : '4pe2usejqcdmhi0a25jp4b5sh3'
    };
    var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
    var userData = {
       Username : 'username',
       Pool : userPool
    };
    var cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
       cognitoUser.authenticateUser(authenticationDetails, {
          onSuccess: function (result) {
             console.log('access token + ' + result.getAccessToken().getJwtToken());
         /* Use the idToken for Logins Map when Federating User Pools with Cognito Identity or when passing through an Authorization Header to an API Gateway Authorizer */
        console.log('idToken + ' + result.idToken.jwtToken);
       },
       onFailure: function(err) {
          alert(err);
       },
    });
    

    从浏览器存储和发送JWT并在API网关验证 .

    • 从登录API endpoints 接收JWT后,您可以使用HTML5 Localstorage,Sessionstorage或Client Side Cookie将其本地存储在用户的浏览器中 . (可选)如果您需要使用服务器端Cookie,则需要具有代理后端,该后端使用Web App保持会话状态并将其转换为JWT以调用API网关 .

    • 从Web浏览器(假设您的客户端直接调用API网关)设置一个名为Authorization的HTTP标头,并将JWT转发给API网关调用 .

    • 在API网关处,使用Cognito Authorizer作为授权令牌,它还将解析的用户身份转发给您的Lambdas .

    注意:这里我有目的地避免了IAM授权,因为它需要Web App JavaScripts的一些额外工作才能在浏览器中实现Signature 4 Signing并且还需要经常刷新令牌,这对于AWS JavaScript SDK很简单,但如果你需要,它将变得复杂自己实现它 .

  • 3

    请看一下这个here .

    该示例演示了各种配置,包括自定义授权器,cognito,lambda,dynamoDB等 .

相关问题