In this lesson, you will learn how to bridge the gap between third-party authentication providers and your local database by synchronizing external user data into a consistent internal schema.
Why Mapping Matters
When a user authenticates via an external provider like Google or GitHub, the data they provide is unpredictable. GitHub might call their unique identifier id, while Google calls it sub. Furthermore, you need to link these external "identities" to a single user_id in your local database so that your application can manage permissions, profile settings, and application-specific data regardless of how the user logs in.
The Normalization Pattern
To handle this, create an Identity (or LinkedAccounts) table in your database. This acts as a junction between the external provider and your local User record. By storing the provider_name and provider_id alongside your local_user_id, you create a normalized mapping.
Here is a simplified approach to handling this lookup when an OAuth callback returns:
async function syncExternalUser(profile) {
// 1. Find or create the local user
let user = await db.users.findOrCreate({ email: profile.email });
// 2. Map external identity to the local user
await db.identities.upsert({
where: { provider_id: profile.id, provider: profile.provider },
update: { last_login: new Date() },
create: {
userId: user.id,
provider: profile.provider,
providerId: profile.id
}
});
return user;
}
Key Considerations
- Consistency: Normalize the raw profile data into your preferred format before touching your database. Don't let external naming conventions bleed into your application logic.
- Account Linking: By mapping multiple identities (e.g., Google and GitHub) to a single
user_id, you allow users to sign in through different providers while maintaining a single, unified local profile. - Data Freshness: Third-party profile data (like avatars or display names) changes. Use the authentication callback as a trigger to update your local cache of the user’s name or email to ensure your UI remains accurate.
Key Takeaway: Always decouple the external provider’s unique identifier from your application by mapping it to a local user_id within a dedicated identity table.