There is a big difference between authentication and authorization, and this is (pretty much) all about authentication. At first, this all can seem pretty easy to implement, but things are much more complex than “we will use an auth library.” The article demonstrates the complexity of the topic, and provides a checklist, of sorts, documenting all of the decisions you need to make before you even start the search for an auth library.
I also offer a few suggestions for how you approach the decision-making process.
First, let’s make sure we’re on the same page. Authentication means identity verification, and authorization checks whether the authenticated entity (usually the user) has sufficient permissions to perform a given operation.
Take a regular Google Account login, for example. If Google tells the app that it’s me (the user with ID 123 and email email@example.com), I’m authenticated, but any further action must go through an authorization process. Can the user write articles? Can the user publish them? And so on. For now, well save authorization for another day.
I’m not a security expert, so I don’t want to go into these topics. Therefore, I will not even address the method of storing sensitive data (i.e. passwords, personal data) and password hashing. There are more knowledgeable people on the topic - here’s a good place to start.
Your first important decision is to choose an authentication scheme. The most basic is HTTP basic - it’s easy to use on the client side, user management is “in one file”, and settings can be made on virtually any HTTP server without the need to change the application (unless we need to work with authorization). However, it is a variant in which user data (name and password) travels over the network with each HTTP request, and there is a high risk of capture and the identity theft that can come with it.
Another standard option is to send a username and password to an application based on session, and have it send its ID in the Cookie HTTP header. This is a much better solution, however Cookie work well in web browsers. What about mobile apps? Or TV? Or a smart thermostat?
OAuth 2.0 has become the industry standard. However, this it serves primarily as a way to enable users of one system to sign in with another, external or third-party application. In fact, the authentication server itself can be an application just logging in and managing users. The external application can be web application (React.js, Angular) or mobile apps (iOS, Android) from the same organization, another server, or another company.
This is a big topic, and there is a lot more to it, but for my purposes here, this scheme allows multiple authentication methods, multiple clients with different user data accesses, and approvals of these hits by the user. It also revokes access to individual clients and instances of one client, and a large number of extensions for smart devices without a web browser.
I will go deeper into these topics in the future, but I’ll start with an overview of the use cases you should be thinking about during the decision process.
Here are the basic use cases that need to be addressed:
How will the user log in?
How does the user change their password?
Do you want to support Single Sign-On (SSO)?
Do you want to support 2FA/MFA?
How can the user logout?
How long is the expiration of the sessions?
You also need to manage these users somehow, otherwise there would be no one to log-in.
How will user registration work?
Is it necessary to activate an account/validate an email address?
How can a user cancel or delete their account?
How do we manage authentication-related emails?
There are more use cases where you need to decide whether to use OAuth 2.0 or OpenID (or generally to provide authentication to third parties).
How does registering a new client work?
How does deactivating/deleting a client work?
How are authorization rules for clients managed?
How does the client request changes in approved client authorization rules?
Do you want to support the possibility for each client to have multiple sub-clients (iOS, Android, Web)?
How and where can the user deny access to previously-approved clients?
How and where does the user revoke individual “sessions” within one client?
How long is the expiration for tokens?
Do we want to use Json Web Tokens (JWT)?
It is possible that you don’t need to answer some of these use case questions today. But what about next year? Or, in five years? Will the system you’re working on today be “simply” expanded with additional features? Is this actually something you want to develop and manage yourself?
Personally, I prefer to take a working system and configure it to my needs. That doesn’t necessarily mean taking 20 libraries and packages and writing code to link and configure them for all parts. For some projects (especially internal), Google Suite (or a similar alternative) supports a feature that you can manage your users and their authorization rules for your apps.
However, a more versatile solution is needed for use on B2C projects because you (usually) do not want to register all of your users for the project internally. One may be Auth0, or alternatives like Okta, Amazon Cognito, OAuth.io. I haven’t tried it myself yet, but I’m sure I’ll use it when a suitable project comes up. Try it and let me know what you think!
I have to say that any single tool, library, package, or service will not help you with the decision on the use-cases listed above. It will help you with subsequent management, maintenance, and scalability. However, you have to figure out what’s best for your project. Take it as an inspiration to think about. You can also keep track of the updated and versioned checklist on GitHub.
Over the coming months, I will go deeper into related topics likes like authorization, OAuth2.0, and its extensions - and the decision-making process around authentication and authorization. Stay tuned!
In the first post of this two part series, we lay down the basic components for building a general string parser. We will use TypeScript and the fp-ts library, and basic knowledge of functional concepts (function composition, immutability) and data types (Option, Either) is expected.
Even in simple, smaller applications we have to deal with configuration of some kind. Since we all know that hardcoding config values sucks, we tend to pick the easy-yet-flexible and powerful method - reading values from environmental variables.
At Cookielab, we use and contribute to many open source projects (OSS). Our primary motivation is not necessarily to give back to the community (which we care about greatly). The fact is that we use open source tools to help us to be more productive, and we usually use them for client-facing work.