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

Add sign in with Facebook and Apple #19

Open
specious opened this issue Nov 8, 2022 · 0 comments
Open

Add sign in with Facebook and Apple #19

specious opened this issue Nov 8, 2022 · 0 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@specious
Copy link
Member

specious commented Nov 8, 2022

Introduction

In order to promote an atmosphere of genuine individual participation and contribution, the Litter Map platform enables users to sign in with their established identity on a well-known and respected third-party platform on which user accounts are known to have a strong tendency to be closely associated with users' real world identities.

At present, it is only possible to sign in with Google, but it would be of considerable value to add the option to sign in with Facebook and Apple as well.

Concepts

The idea is to implement server-side authentication using a well-known and reliable third-party service in order to establish a user's identity.

Familiar identity providers (such as Google, Facebook and Apple) provide OpenID Connect identity verification via the standardized Open Authorization a.k.a. OAuth protocol as a free-to-use service.

Technical information

Links to detailed information on how to implement third-party sign in with the three major identity providers:

The exact features that each of them supports can be viewed by checking the published well-known discovery endpoints (best viewed with firefox or httpie), which are intended for clients to be able to dynamically determine the exact capabilities offered by an OpenID Connect service provider:

Implementation

The following describes in detail the familiar "sign in with {Google,Facebook,Apple,...}" process that we are all familiar with.

In order to be secure, it must be implemented carefully, and potential weaknesses should be duly noted.

The authentication is performed using OAuth's authorization code flow, which is the most secure flow (also referred to as "grant type" in the documentation) offered by OAuth 2.0.

  • When the user wants to log in, the frontend client calls /login/{service} on the backend
  • The backend generates a secret value based on the user session, which is a value that only this backend and the client which the session belongs to should know1
  • The backend prepares a redirect URL that will direct the browser to send the user to the third-party sign in page, with information included regarding where the third-party service should send the user back to2 after verifying the user's identity (specifically, the /auth/{service} endpoint on the backend)
  • The browser now takes the user to the third-party login page which verifies the user's identity (and informs the user exactly which permissions are about to be granted) and then asks the browser (via a redirect response) to send the user back to the backend, but this time to the /auth/{service} endpoint, as specified in the redirect_uri parameter in the previous step, with the original state token and also a generated authorization code included as query parameters
  • The backend confirms that the secret value embedded in the state token has not been counterfeited (by a party that doesn't know the secret) in order to guard against request forgery; this establishes that the sign in flow has not been tampered with
  • The temporary single-use authorization code (which isn't secret, since it is passed to the browser as a query parameter in the redirect URL) combined with the client secret that should only be known to the third-party identity provider and this backend (its purpose is to prevent client impersonation), is then exchanged for a long-lived access token, which is an access key the backend can use to request information that the user agreed to let it request
  • The backend then uses the access token to request the user's personal details from the third-party identity provider
  • As of this writing, the backend does not hold on to the access token after this; however, saving this access token would make it possible to later refresh the user's profile information until the access token expires

Keep in mind that the client id and client secret are passed to the lambda functions as external environment variables (which at present are set during deployment using stack parameters), in order for those values to not be present anywhere in the code.

To summarize, the functions involved are:

Remembering user accounts

In the current implementation, distinct user identities are saved in the users table keyed as g: (for google) concatenated with their google profile id.

If we were to continue with this system, the same users would end up signing in as distinctly separate identities (e.g., a:{apple-id} and :f{facebook-id}, as previously noted in #6).

In order to unify them, what we should do is re-key the users by email address (this implies that we are confident that the third-party service has verified that the person owns that email address), so that we can recognize the same user when they sign in using different third-party providers.

Reconciling accounts

In cases where a person is using different email addresses with different third-party identity providers, there won't be an automatic way to merge their profiles into a single user account.

Therefore, it will be worth considering a way to let users manually connect their accounts.

Choice of profile picture

Once a person signs in with more that one third-party identity, multiple profile pictures associated with those accounts may become available. Once support for multiple identity sources is implemented, it should therefore make sense to create a way that a person can select which profile picture they would like to use (or even upload a custom picture instead).

Footnotes

  1. A malicious party obtaining the user's session id is tantamount to hijacking the user's identity with the site, so it is extremely important to take proper care when handling the session id value and to put guards in place to discourage unauthorized activity.

  2. The allowed redirect_uri values must also be registered with the third-party provider

@specious specious added enhancement New feature or request good first issue Good for newcomers labels Nov 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

1 participant