在无服务器/单页面Web应用程序中使用Amazon Cognito的授权代码授予

时间:2019-03-16 14:28:15

标签: javascript amazon-web-services authentication oauth-2.0 amazon-cognito

我正在尝试开发一个无服务器JavaScript Web应用程序,该应用程序由API Gateway(带有Amazon Cognito自定义授权程序),Lambda和DynamoDB组成。这篇文章是我使Cognito完全满足我的需求之前的最后尝试(完全第二次)。由于Cognito文档令人困惑和缺乏,我将尝试注入我所学到的东西。

使用Cognito,您可以使用自己的注册,登录等网页开发自定义身份验证工作流。您还可以选择利用Amazon的Hosted Web UI使事情变得简单一些(尽管很少有HTML / CSS自定义选项)。 我正在使用后者。

在为Cognito用户池配置App Client时,您必须做出的最关键决定是使用授权码授权还是隐式授权。使用授权码授予,成功的身份验证将向您的调用者返回包含JWT id_token,access_token和refresh_token的会话令牌。使用“隐式授予”,您的呼叫者将收到一个授权码,该授权码可用于仅获取id_token和access_token,而无需refresh_token。隐式授予最适用于无服务器(或单页)应用程序,因为它不会向客户端公开长期存在的refresh_token,而该令牌很容易被破坏并用来假定对应用程序的有效访问。但是,access_token的固定到期时间为一小时,目前无法配置。因此,如果没有刷新令牌以静默方式更新access_token,则您的用户将不得不每小时登录一次。

由于我的Web应用程序绝不包含敏感信息,因此,我将使用授权代码授予并将令牌保存在浏览器的LocalStorage( )中,这是不安全的,不建议这样做,也是一种不良做法 ),希望Cognito在某个时候能够完全遵守OpenId Spec并为refresh tokens with implicit grants via prompt=none提供全面支持。如您所见,亚马逊对此事一直没有回应。哎呀,即使是自定义access_token的过期时间(带有隐式授予)的选项也将是一个不错的选择。

因此,我已经从amazon-cognito-auth-js JavaScript库成功部署了示例应用程序,该库应与Hosted Web UI流一起使用。请勿将其与amazon-cognito-identity-js库混淆,如果您正在开发自己的自定义身份验证工作流,则应使用该库。 amazon-cognito-auth-js库同时支持授权代码授权和隐式授权,并将处理解析令牌,将令牌缓存到本地存储/从本地存储检索令牌,以及使用刷新令牌以静默方式更新access_token(用于授权代码)授予)。

登录时,我的浏览器URL类似于以下内容:https://www.myapp.com/home?code=ABC123XYZ ...,并且在浏览器的LocalStorage中设置了三个JWT令牌。但是,如果我立即刷新页面,则会收到“ invalid_grant”错误,因为授权代码仍在URL中并且已经被使用。我是否应该在成功登录后进行页面重定向以从URL中删除授权代码?这是我计划从应用程序中每个页面的onLoad()调用的主要代码:

function initCognitoSDK() {
        var authData = {
            ClientId : '<TODO: your app client ID here>', // Your client id here
            AppWebDomain : '<TODO: your app web domain here>', // Exclude the "https://" part. 
            TokenScopesArray : <TODO: your scope array here>, // like ['openid','email','phone']...
            RedirectUriSignIn : '<TODO: your redirect url when signed in here>',
            RedirectUriSignOut : '<TODO: your redirect url when signed out here>',
            IdentityProvider : '<TODO: your identity provider you want to specify here>', 
                    UserPoolId : '<TODO: your user pool id here>', 
                    AdvancedSecurityDataCollectionFlag : <TODO: boolean value indicating whether you want to enable advanced security data collection>
        };
        var auth = new AmazonCognitoIdentity.CognitoAuth(authData);
        // You can also set state parameter 
        // auth.setState(<state parameter>);  
        auth.userhandler = {
            onSuccess: function(result) {
                alert("Sign in success");
                showSignedIn(result);
            },
            onFailure: function(err) {
                alert("Error!" + err);
            }
        };
        // The default response_type is "token", uncomment the next line will make it be "code".
        auth.useCodeGrantFlow();
        return auth;
    }

1 个答案:

答案 0 :(得分:0)

如果您的应用程序可以在浏览器本地存储中找到有效的访问令牌,并且可以忽略查询字符串中收到的代码,则可以重定向以从查询字符串中删除代码,也可以检查页面加载情况。