User + Account + Session
A minimal relationship between users, accounts, and sessions.
Entity-Relationship Diagram
Relationships
IDs
The unique ID used for user and session tables can be created using CUID or UUID.
User
- A
usercan be visualized as a physical person. - A
userhas zero or moreaccounts, which is a way for them to authenticate. - A
userhas zero or moresessions, which represents a successful log in.
Session
After a user successfully authenticates to one of their accounts, a new session should be created.
- A
sessionshould not be easily fingerprintable. - A
sessionshould expire. - A
sessionneeds to be associated with an existinguser.
Account
An account is uniquely identified by a user_id, provider_id, and provider_account_id.
- User ID: The owner of the account.
- Provider ID: The ID of the provider that will handle authentication.
- Provider Account ID: The ID of the user under that provider.
Examples
| user_id | provider_id | provider_account_id |
|---|---|---|
| cuid_id_1 | auth0 | user@auth0.com |
| cuid_id_2 | battlenet | user@battlenet.com |
| cuid_id_3 | discord | user@discord.com |
Authentication Flows
Sign Up (Google OAuth)
Visit Login Page
User visits /auth/login/google to authenticate with Google OAuth.
Complete OAuth approval
User gets redirected from application to Google OAuth page and approves application.
Visit Callback Page
Google redirects user back to application, and application handles callback.
Exchange OAuth code for token
After exchanging code for token, application gets information:
{
"sub": "12345"
}Handle Sign Up
Application does not find an account with provider_id=Google and provider_account_id=12345.
User is signed up.
Log In (Google OAuth)
Visit Login Page
User visits /auth/login/google to authenticate with Google OAuth.
Complete OAuth approval
User gets redirected from application to Google OAuth page and approves application.
Visit Callback Page
Google redirects user back to application, and application handles callback.
Exchange OAuth code for token
After exchanging code for token, application gets information:
{
"sub": "12345"
}Handle Login
Application *does find an account with provider_id=Google and provider_account_id=12345.
The process of user and account creation, linking, etc. can be seen in the flowchart
Remarks
Account Credentials
This minimal set up does not handle provider account credentials. See basic+credentials for an example with credentials.
Examples
A user logs in with username and password combination.
A user logs in via Google and generates a refresh_token for their account.
This can be stored in the database and used to access Google resources on the user's behalf.
| user_id | provider_id | provider_account_id | provider_account_credential |
|---|---|---|---|
| cuid_id_4 | credentials | user@email.com | password |
| cuid_id_5 | user@gmail.com | eyJhbGciOi... |
Refresh
This minimal set up does not handle refresh. See basic+refresh for an example with refresh behavior.
Concept
Attach a unique refresh code (e.g. UUID, CUID) to each session in the database, and store this separately from the session (e.g. in a separate cookie).
The refresh information should be set to expire after the session information. For example the session may expire after 1 day, and the refresh after 1 week.
When the session expires, find and read the refresh information if it exists. Find a corresponding session that has this unique refresh code. If it exists:
- Update its expiration date.
- Generate a new, unique refresh code.
- Store the new session and refresh information.