littermap / littermap-aws-backend

Cloud-native backend for the Litter Map application -- (Join us on: https://discord.gg/JvEQMSQaYr)
https://littermap.com
GNU Affero General Public License v3.0
3 stars 2 forks source link

Add sign in with Facebook and Apple #19

Open specious opened 1 year ago

specious commented 1 year ago

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.

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).

[^session-security]: 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.

[^redirect-uri]: The allowed redirect_uri values must also be registered with the third-party provider