Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure my signout is a real signout #253

Closed
douglasnaphas opened this issue Nov 21, 2020 · 27 comments
Closed

Make sure my signout is a real signout #253

douglasnaphas opened this issue Nov 21, 2020 · 27 comments

Comments

@douglasnaphas
Copy link
Owner

I think I currently have a halfhearted signout, that leaves the cookies in place.

@douglasnaphas
Copy link
Owner Author

Relates to #248.

@douglasnaphas
Copy link
Owner Author

@douglasnaphas
Copy link
Owner Author

This definitely belongs in v4.

@douglasnaphas
Copy link
Owner Author

I should set an expiration time on the cookies, in case people don't actively logout.

@douglasnaphas
Copy link
Owner Author

I should make sure there's an expiration date on my non-JWT cookies as well.

@douglasnaphas
Copy link
Owner Author

douglasnaphas commented Aug 15, 2021

TODO

  • Add /get-cookie to backend, issuing an opaque cookie. It would be OK, though ambitious, to add this as a synchronous EventBridge/Step Functions workflow CDK support for APIGW-StepFunctions integration isn't sufficient. Also, I'm going to add opaque cookie issuing and checking to the existing login- and cookie-related endpoints, and then delete the unnecessary JWT-related code from those same endpoints.
  • Handle the case where the person is in no seders at /#/seders (Spinner just spins at /#/seders if no seders are joined #264).
  • Add opaque cookie issuing and handling to existing login- and cookie-related endpoints.
  • Delete unnecessary JWT-related code from login/cookie endpoints.
  • Add a /clear-cookies endpoint I'll add opaque cookies onto the existing endpoints, to make for an easier transition.
  • Add a /clear-jwts endpoint. Maybe (probably) rename it to /clear-cookies.
    • Make a test of /clear-jwts using supertest.
  • Make the logout button on the frontend hit /clear-jwts /clear-cookies.
    • Make a failing unit test checking whether the Log Out button is inactive until /clear-jwts /clear-cookies returns.
    • Get the Log Out unit test passing.
    • Run the e2e test locally against the deployed dev site.
    • Make the e2e test look for JWTs the opaque cookie in the logged-in browser after the game is over. I'll need to use Network.getAllCookies to get the JWTs cookie, as it and my other legacy cookies are HttpOnly. I can get them with var data = await page._client.send('Network.getAllCookies');.
  • Make the e2e test click logout.
  • Make the e2e test check for expired JWT cookies, and fail. I'm not sure what this will look like.
  • Set an expiration date on all cookies. There wasn't really ever an advantage to me using session cookies anyway.
  • Switch from the old cookies to the new cookie.
  • Add a madliberation user id. Or maybe the email address, normalized to lowercase, is the user id.
  • Separate endpoints for, eg, /join-seder and /join-seder-signed-in. Otherwise endpoints could partially succeed.
  • Use lambda authorizers. Or APIGW cookie (?) authorizes? Probably not. Or maybe... Maybe I could use a Cognito authorizer for the path that turns Cognito cookies into ML cookies, and a Lambda authorizer for paths that require sign-in. The main drawback of Lambda authorizers was that they only offer authorization based on a token or request params, but not both, and I want to use both so that the front end and back end are always on the same page about who the user is, but I could do that part in the app code. There's also the issue of WS APIs only allowing request param auth.
  • Delete legacy cookie code.
  • Gracefully handle what happens if someone tries an authenticated action with no cookies
  • What about if someone's opaque cookie expires while they're midway through an authenticated seder?
  • Add a Smoke Action (efcbd13) so that the hastened itest from this branch can become permanent

@douglasnaphas
Copy link
Owner Author

douglasnaphas commented Aug 15, 2021

On deleting cookies server-side (set Expires in the past).

@douglasnaphas
Copy link
Owner Author

I'm re-prioritizing this ahead of WebSockets. I think I only temporarily put WebSockets ahead of it because I was curious whether the WebSocket connect handler receives cookies. It does.

@douglasnaphas
Copy link
Owner Author

I'm still continuing work for this on the 250-ws1 branch for now, though.

@douglasnaphas
Copy link
Owner Author

What about users who still have old cookies in their browsers for Passover 2022?

douglasnaphas added a commit that referenced this issue Sep 5, 2021
douglasnaphas added a commit that referenced this issue Sep 5, 2021
gh-253

My last build failed when it tried to curl a host of https
@douglasnaphas
Copy link
Owner Author

Do I even need access and refresh tokens? I'm not delegating authorization like with OAuth2.0. Should I be issuing my own cookie? If I do, what happens when it expires? How about...it's expired, and the person has to log in again. I bet my frontend doesn't handle that course of events (expired cookies of any kind) at all.

@douglasnaphas
Copy link
Owner Author

I think a big part of the whole problem around signout, gh-331, etc, is that my frontend is confused about who is signed in. It should, as part of this or any of this batch of Issues:

  1. Ask the backend on each load for an authoritative decision about whether the cookie sent with the request is for a logged-in user, and if so, the logged-in user's email address.
  2. If they're not a logged-in user, but they once were (?), like if the cookie is found but expired (but if I'm expiring cookies by a cookie attribute, an expired cookie will never get sent, so I won't be able on the backend to distinguish between a user who logged in too long ago and a user who has never logged in), or if some state on the front end claims that the user is logged in, then they should go to a you-have-been-logged-out page.

@douglasnaphas
Copy link
Owner Author

Ugh, what if someone logs in, joins a seder, logs out in another tab, and submits their libs in the tab where they're logged in?

@douglasnaphas
Copy link
Owner Author

I should stop sending the id token to the client, and instead associate the identity server-side with the…sub? Id token on the client creates multiple sources of truth.

@douglasnaphas
Copy link
Owner Author

The whole login/logout behavior is getting really hard to manage. I think I need to list all the different features I want, how I want it to work.

@douglasnaphas
Copy link
Owner Author

I think I do want to move to a passover.lol-generated opaque cookie. Advantages:

  • Less noise in the dev tools.
  • Less data sent around.
  • Less backend complexity because I can throw out the refresh token logic. I can just have the opaque cookie last as long as I want it to, that is, as long as the refresh token would have been valid for. When the opaque cookie expires, they're logged out, just as they would have been whenever their refresh token expired.
  • Less backend complexity around cookie-checking after initial login.
  • No more abuse of access tokens--I should not be using OAuth2 access and refresh tokens because I'm not doing delegation of authorization.

I should still, during the cookie-checking process, check back with Cognito to see if the person has deleted their user.

@douglasnaphas
Copy link
Owner Author

Side note: maybe the backend auth'd user recordkeeping should be limited to "this email address was this user in these rooms."

douglasnaphas added a commit that referenced this issue Dec 30, 2021
gh-253

Since I'm planning to mess with cookies, I want signin exercised on this
dev branch.

I may leave these changes to the itest App in place on master, and add a
Smoke Action that runs the smoke test every day.
@douglasnaphas
Copy link
Owner Author

The login cookie should be non-session.

douglasnaphas added a commit that referenced this issue Mar 16, 2022
gh-253

I don't know how to do what the commented-out test here is doing. I
don't know how to test that my runXXX Dynamo functions actually set the
locals they're supposed to set.
douglasnaphas added a commit that referenced this issue Mar 16, 2022
gh-253

This actually tests that, when I have a function like runGet that runs a
DynamoDB get(), the locals like dbError and dbData are set.
douglasnaphas added a commit that referenced this issue Mar 16, 2022
douglasnaphas added a commit that referenced this issue Mar 16, 2022
gh-253

I'm getting a real error on authenticated requests, a db error when
trying to get the email.
@douglasnaphas
Copy link
Owner Author

I'm quite worried about how the front-end will handle expired logins.

douglasnaphas added a commit that referenced this issue Mar 16, 2022
gh-253

We authenticate with the email now, not the sub.
@douglasnaphas
Copy link
Owner Author

douglasnaphas commented Mar 16, 2022

TODO 2022-03-15

  • Get rid of the front-end's call to /id. Get the nickname and email from the URL instead.
  • Banish sub from the front-end.
  • Have the frontend reasonably handle expired sign-ins. I might have adequate instructions already, since I think with some 400s I say "if you are logged in, try logging out," "try in a different browser," etc.

douglasnaphas added a commit that referenced this issue Mar 16, 2022
gh-253

The evaluate happens in the browser, so it doesn't know user2's name
unless I pass it in.
douglasnaphas added a commit that referenced this issue Mar 16, 2022
gh-253

I started sending more 400s rather than 401s, because the 401 docs say
something about you must send instructions on how to authenticate.
douglasnaphas added a commit that referenced this issue Mar 16, 2022
gh-253

We’ll get the user info from the URL.
douglasnaphas added a commit that referenced this issue Mar 16, 2022
gh-253

I run itest with npx now.
douglasnaphas added a commit that referenced this issue Mar 16, 2022
douglasnaphas added a commit that referenced this issue Mar 17, 2022
douglasnaphas added a commit that referenced this issue Mar 17, 2022
gh-253

The front-end now never interacts with JWTs.
douglasnaphas added a commit that referenced this issue Mar 17, 2022
gh-253

The frontend now figures out who is logged in by looking at params sent
back after login in the redirected-to URL, not by hitting /id.
@douglasnaphas
Copy link
Owner Author

douglasnaphas commented Mar 17, 2022

I might need to bring back some kind of /id endpoint. If you load a new page after signing in, and you have a valid cookie in your browser, you could be kind of signed in without your UI telling you that you are. This could probably be addressed after web sockets, because you aren't really signed in when this happens. The front end has to affirmatively include the email address in requests, even if there is a valid cookie, for anything to happen on behalf of the user. This appears to be addressed in recent commits, in which I update the state hydration to look for just email and nickname.

@douglasnaphas
Copy link
Owner Author

gh-400 is created to handle invalidating the opaque cookie server-side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant