Skip to content

Initial implementation of server-side auth

Lukas Möller requested to merge server-side-auth into master

Fixes #221 (closed), #219 (closed).

Backend

This MR implements the authorization code flow as defined in the OAuth2 specification. A login request is initiated when a user agent navigates to /api/auth/login. This login endpoint does the following:

  • it generates a cryptographic nonce which is stored encrypted as a cookie,
  • constructs a URL which can be used to authorize the user using the OAuth Provider,
  • this URL contains an opaque string parameters (state) which we use to save the redirect_url & the nonce,
  • we then redirect the user to that URL

After the user completes the login action he gets redirected back to /api/auth/callback where the callback handler is executed. There we

  • check whether the state we get as a query parameter has a matching nonce,
  • extract the authorization code passed as a query parameter,
  • use the code and our client_secret to request a set of tokens,
  • store these tokens and redirect the user back to the path they came from.

The logout endpoint simply clears all of these cookies by responding with set-cookie headers which have an expiration date in the past.

A /api/auth/refresh endpoint can be used by the FE to ensure that the cookies always contain valid tokens. Before they expire the client simply has to create a request to the endpoint, the backend will then exchange the refresh token + client_secret for a new token set.

Frontend

We use a non-httpOnly cookie to detect the validity of the tokens stored in our cookies (which the frontend can't read because they are httpOnly). We schedule a /refresh request just before the access token expires and once the token is about to expire also block new API calls by awaiting a global promise.

Deployment

Code flow has to be enabled prior to a production deployment. Legacy user session themselves will continue to work, the auth_backend.py changes are backwards compatible and will accept requests from old frontend instances.

TODO
  • Check if refreshing really work
  • Figure out how to handle CNAMES <- help wanted
Edited by Lukas Möller

Merge request reports

Loading