Can we make our auth schema better?
<aside> ➡️ We’ll go through a few auth schema possibilities. For each schema, I’ve written the Prisma models and some example JSON objects (click on the triangle to expand).
I’ve then listed out some pros 🟩 and cons 🟨, feel free to edit them.
</aside>
Let’s start with the first approach where all the needed fields are stored on the Auth
entity. In the future, if would need extra fields, we would add them there as well.
model Auth {
id String @id @default(uuid())
// Both email and username are here and both are optional (read more below)
email String? @unique
username String? @unique
password String?
isEmailVerified Boolean @default(false)
emailVerificationSentAt DateTime?
passwordResetSentAt DateTime?
// Connection to possible social auth providers
providers OAuth2Provider[]
// Connection to the business logic user
userId String? @unique
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model OAuth2Provider {
id String @id @default(uuid())
provider String
providerId String
authId String
auth Auth @relation(fields: [authId], references: [id], onDelete: Cascade)
}
Pros 🟩
Cons 🟨
email
is required and username
doesn’t exist)model Auth {
id String @id @default(uuid())
// Connection to possible auth providers
identities AuthIdentity[]
// Connection to the business logic user
userId String? @unique
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model AuthIdentity {
providerName String
providerUserId String
// The bread and butter of this idea: dynamic JSON field
providerData Json
authId String
auth Auth @relation(fields: [authId], references: [id], onDelete: Cascade)
@@id([providerName, providerUserId])
}