GithubHelp home page GithubHelp logo

Comments (6)

rpattcorner avatar rpattcorner commented on July 19, 2024 1

Wrapup

I think we've got a handle on this issue now, and want to document what we've learned in case others stray down this particular rabbit hole.

Cutting to the chase, the problem at its core was that the logout chain resulted in Cognito loading a cached version of the app held in local storage. The cached version failed multiple CSP tests that would be passed by a version loaded from Cloudfront. The simple solution is on the application side:

window.localStorage.clear();

Do this just before you redirect to the /signout URL that calls the signout lambda. Duh.

But we also took some time to switch to the Amplify framework so we could explicitly initialize storage with cookie (not local) storage. Both changes were probably necessary.

Finally, in passing, the way that some browsers show cookies and local storage can be confusing to the uninitiated (that's me :)). For example, Brave, my current favorite shows a cookie and storage display like this:

image

which led me to think the cookies were being somehow stored in local storage. I now think this is probably false. The cookies may (?) be just fine, the way to parse the line is "17 cookies. And also some local storage."

Hope this is helpful to somebody down the road.

from cloudfront-authorization-at-edge.

ottokruse avatar ottokruse commented on July 19, 2024

Having tokens in LocalStorage could mess things up, if the JavaScript app is configured wrongly. If configured correctly for Auth@Edge, I would not expect any tokens to be stored in LocalStorage.

First note, Auth@Edge would never write to browser local storage -- server side code cannot do that, only JavaScript running in the browser can.

What I presume must have happened, is that your JavaScript was not initialized with cookieStorage - and Amplify (/Cognito identity SDK) by default uses localstorage. So this became mixed up.

So to configure your Amplify JavaScript App for cookieStorage (instead of localStorage) use code such as:

Amplify.configure({
  Auth: {
    ...
    cookieStorage: {
      path: "/",
      expires: "",
      domain: "your.domain.name.here",
      secure: true,
    },
    ...
  }
});

The Cognito Identity SDK also support this setting (don't know from the top of my head what it is called but the key is using CookieStorage instead of the default LocalStorage).

Does that make sense?

from cloudfront-authorization-at-edge.

rpattcorner avatar rpattcorner commented on July 19, 2024

It does. We're not using Amplify - I'm increasingly convinced we should have done, but it would mean a significant refactoring. Cognito Identity SDK does indeed have something similar, per the pattern below, but I see nothing similar in our code, and our Angular developer is on another gig, so it may need to wait. Apparently you set the storage mode when you call a factory (?) to get the userPool, and again when you construct the userData object.

from the api doc:

 var poolData = {
     UserPoolId : '...', // Your user pool id here
     ClientId : '...' // Your client id here
     Storage: new AmazonCognitoIdentity.CookieStorage({domain: ".yourdomain.com"})
 };

 var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

 var userData = {
     Username: 'username',
     Pool: userPool,
     Storage: new AmazonCognitoIdentity.CookieStorage({domain: ".yourdomain.com"})
 };

Thanks for pointing us in a potentially good direction

from cloudfront-authorization-at-edge.

rpattcorner avatar rpattcorner commented on July 19, 2024

@ottokruse It looks like setting the cookieStorage (in either API) depends upon a style of initiating authentication as some kind of context in the root of the app.

Do you think that means that a different approach that simply uses the JWT supplied by a default cognito hosted ui login, to update the app's AWS.config object with the AWS.CognitoIdentityCredentials received direct from Cognito has the downside of disallowing a configuration that uses cookies instead of the default local storage?

What mischief do you suppose using local storage instead of ordinary cookies might generate over and above having to manually destroy the local storage when an alt domain changes?

from cloudfront-authorization-at-edge.

ottokruse avatar ottokruse commented on July 19, 2024

The Auth@Edge solution needs cookies.

Reason: browsers send cookies along automatically in requests to the web server - so Lambda@Edge can inspect the tokens in the cookies.

Whatever is in local storage is not send along automatically by browsers to the web server. Usually your JavaScript app uses tokens from local storage when doing XHR requests to protected API's (and you have to explicitly code that, i.e. add the token as header on those XHR requests). This is another paradigm, Auth@Edge is not (only) about protecting XHR, but (primarily) about protecting the SPA from being downloaded in the first place (as main web page).

If you configure you Amplify/CognitoSDK enabled web app with cookie storage from the get go, so it can work with Auth@Edge, you will never have JWTs in localstorage that you need to clean. Not that it matters a whole lot to change later: if you configure Amplify/CognitoSDK for cookieStorage then they will ignore tokens in local storage, and try to get (and save) tokens in cookies.

from cloudfront-authorization-at-edge.

rpattcorner avatar rpattcorner commented on July 19, 2024

And yet (referring to a 19th century critique of the bumblebee), the current setup works.

I guess the question is whether we can configure the CognitoSDK to use cookies (which I'd prefer) while retaining the simplicity of the default Cognito interface, which seems to require neither Amplify or a CognitoSDK instantiation of a UserPool with explicit cookie-based storage. You'd think there would be an option on the UserPool itself...

from cloudfront-authorization-at-edge.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.