This is an Epic Stack example which demonstrates how to implement authentication using an OpenID Connect provider.
In this example, we have three forms of authentication:
- Username/password (built-into the Epic Stack)
- GitHub OAuth2 (built-into the Epic Stack)
- Google OpenID Connect (implemented in this example)
There are no database schema changes necessary for adding an OIDC provider (like Google). There are two ways to go about adding another auth provider.
- You can duplicate a lot of the GitHub auth code because much of it will be the same. I did that in this commit.
- You can make the provider stuff generic and use it for both GitHub and OIDC, which is what the final version of this repository looks like (and what I would recommend if you plan on having more than one auth provider). You'll find that work in this commit which builds on the first.
This example uses web-oidc and remix-auth to implement the OIDC authentication flow. This example doesn't deal with refresh tokens because we're only using the OIDC provider for authentication. If you need to use refresh tokens, then you'll need to store them in a database and use them to get new access tokens when necessary.
Because we've made the auth provider generic, adding a new one is relatively straightforward:
- Add the provider's name in
app/utils/connections.tsx(export const {YOUR_AUTH_PROVIDER}_PROVIDER_NAME = 'your-auth-provider') and add that to theproviderNamesarray. This will create type errors which once fixed, will ensure that you've updated all the necessary places. - Create a new file for them in
app/utils/providers/{provider-name}.server.tsand follow the pattern of the other providers by implementing theAuthProviderinterface. - That's it, you're done.
You'll probably be required to set up private keys and other things which will
likely require a bit of work in .env.example, .env, and
app/utils/env.server.ts.
The cool thing about this approach is it doesn't actually make a difference
whether you're using an OIDC provider or not. As long as you satisfy the
AuthProvider interface, you're golden (which is why GitHub's OAuth2 provider
is supported in the same manner).
