Skip to content

Authentication

Jon Riecke edited this page Jan 31, 2023 · 1 revision

Objective

One of the key requirements of the Planscape tool is collaboration: the ability to share, review, and add feedback on plans created in the tool. Planscape needs to support user accounts and authentication (signup/login/logout). This doc will detail the technical design for the authentication layer and user data.

See Planscape Technical Design.docx for more details on the requirements.

Design

Since we are using a Django backend and an Angular frontend, both layers will need to handle different parts of authentication and user data.

The backend is responsible for:

  • Providing HTTP endpoints for creating, updating, and deleting user accounts
  • Providing HTTP endpoints for logging registered users in and out
  • Returning appropriate error status codes (e.g. 401) when user credentials are not included in the request header and the requested resource is not publicly viewable
  • Storing user accounts and session tokens, with appropriate timeout durations for the latter

The frontend is responsible for:

  • Displaying login and registration forms and posting form submissions to the backend
  • Validating form fields and displaying errors with login and registration
  • Restricting/allowing access to parts of the application depending on whether a user is logged in
    • Product guidance: The application should be navigable by a signed out user, but only a logged in user can create/edit/save plans and view or comment on non-public projects
  • Rerouting to the login form if the user tries to access restricted parts of the application while logged out
  • Storing a JWT (JSON Web Token) cookie that can be used to refresh or validate a user session
  • Providing a button for the user to logout
  • Providing a section of the application for the user to manage their account, e.g. changing password or email address
  • Sending credentials for the logged in user with each HTTP request to the backend

Backend design

Fortunately, Django libraries already exist that take care of most or all of our backend requirements. dj-rest-auth provides a set of REST API endpoints to handle user registration and authentication tasks, and is integrated with Simple JWT to provide JWTs to use with separate frontends (like Angular).

Based on initial investigation, it looks like we can rely on these libraries and write no or very little backend code to handle user authentication.

Frontend design

Since our frontend is in Angular, we will handle authentication using a combination of components and services:

  • LoginComponent, a login component to display a login form and call the login method on AuthService on submission. This component should also include a link to SignupComponent.

  • SignupComponent, a signup component to display a new user registration form and call the register component on AuthService on submission. This component should also include a link to LoginComponent.

    • MVP: new users are required to register using an email address.
  • HomeComponent, a landing page to display when the user logs in. We may instead direct a newly logged in user to one of the user flows, possibly Explore (which will have its own component).

  • AuthService, an authentication service that handles HTTP requests to the Django REST API endpoints from LoginComponent and SignupComponent, as well as any other component that needs to access user data. It should expose at least the following service methods:

    • login(): logs an existing user in
    • register(): registers a new user
    • logout(): logs out the current user
    • isLoggedIn(): returns true if there is a logged in user
    • getLoggedInUser(): returns an object representation of the logged in user

Logout doesn't need its own component and can simply be a link in the nav bar that calls the logout method on AuthService.

Routing

// TODO: link to design doc for user roles and permissions when it's ready

Some components should only be routable if the user is signed in. For example, the user should only be able to load project plans if they are logged in and have permission to view, unless the viewing permissions for that project are set to "anyone with the link can view."

The AppRoutingModule should guard these sensitive components with an AuthGuard. AuthGuard is a class that checks the following:

  • Viewing permissions on the component/project/plan
  • The signed in status of the current user
  • The current user's viewing permissions

before navigating to the component. If the user isn't signed in or doesn't have permission to view the component, the AuthGuard can redirect to the LoginComponent.

Social media authentication

Many web applications offer social media authentication, allowing users to login using their existing social media accounts (e.g. Facebook, Google, Twitter) instead of creating new accounts specific to the web application.

There are Django libraries that make this easy to do (e.g. django-allauth) but we would have to register our application with each social media provider to obtain the required project keys. For example, to support Google OAuth2, we would have to create and provision a Google Cloud project. Likewise for Microsoft and Azure. This may or may not be free.

Social media authentication is a nice-to-have for Google and Microsoft in particular, but we can wait until the tool is closer to launch before looking into registering with cloud providers and figuring out costs.

Testing

Since we are writing no or very little backend code, we probably don't need additional backend tests; the libraries we're using are presumably well-tested.

We should have unit tests in TypeScript for the frontend AuthService, AuthGuard, and all components that handle user authentication (LoginComponent, SignupComponent, etc.).

Open questions

  • User groups are mentioned in the Technical Design doc. I have questions about these groups—can anyone create them and add users to them? Does the tool come with any groups predefined?
  • Do we need a way for the user to view other users' profiles or search for users in the tool, or can they just add people by email address?
  • Should we allow account deletion? What happens to the plans created by a user if their account is deleted?
  • What should show up on a user's profile? What about viewing your own profile vs. someone else's (if there is profile discovery in the tool)?
  • A UX mockup of the login/signup and profile screens would be useful
Clone this wiki locally