Thoughts on implementing local and social logins on a website

Hi. This is the eighteenth part of the diary about developing the “Programmers’ diary” blog. The open source code of this project is on https://github.com/TheProgrammersDiary.

The first diary entry explains why this project was done: https://medium.com/@vievaldas/developing-a-website-with-microservices-part-1-the-idea-fe6e0a7a96b5.

Next entry:

—————

2024-12-24

[Note: these brackets: [] mean a different point of view which was formed after the date this entry was written].

Let’s continue with social login.

Now we have user table with email, username and encrypted password. And here we have a problem. We can’t have a social login password. If we e.g. allow a user to sign in with Google, it must be redirected to a site Google owns, where Google will confirm the user’s identity. We can’t send a password of Google account ourselves because we could have security holes in our system, and these holes could provide access to many user’s applications.

One of my colleagues told me and example of why redirection to the social login site must always happen: suppose we log incoming requests. Suppose we are not malicious and will not steal passwords. However, we accidentally expose access to Kibana board (which displays logs) and a hacker checks the board, stealing social login passwords. Therefore, we never deal with social login passwords, we must redirect to the social login site which will confirm the user’s identity.

Continuing on the problem: since local login needs a username and a password while social login only needs a username stored, we should think about how our database should be designed.

Three approaches I see:

  • One table for normal/social logins. Pros: Simplest to implement. Cons: We need to be careful how we handle missing passwords for social logins. Failure to account for this might lead to a disastrous security breach: Suppose user creates an account via social login. We write NULL in a password column. Then, A hacker uses a local login form, sends a username with a NULL password, we see password in the database is null and authorizes the hacker. To prevent that, we could validate to check that the user always sends a password if the login is local.

  • Two tables: one for local, one for all social (Google, Twitter, Github ect.) logins. Pros: Our code is unlikely to have NULL password issues. Cons: If we are filtering all users we would need to join two database tables.

  • A different table for each different login (one for local, another for Google, another for Twitter ect). Pros: We can have different user information with different logins [It would probably be easier to have a different table for user data other than username, email and password]. Cons: Hardest to implement. [Database joins would be a pain in the head.]

I would pick between one/two tables. The Two two-table approach seems safer, yet for now it seems that vulnerability only exists if the database threats NULL = NULL. In Postgres NULL ≠ NULL. [Wrong view: if we switched the database which treats nulls as equals and forget to change the application code would be in big trouble. The login issue we are solving must be implemented on the application side.]. Let’s pick the first option since it is easier to implement and we can prevent the mentioned issue.

—————

Thanks for reading.

The project logged in this diary is open source, so if you would like to code or suggest changes, please visit https://github.com/TheProgrammersDiary.

You can check out the results of the project: https://www.programmersdiary.com/.

More diary entries coming soon.