A feature-complete general-purpose OAuth2 client built using Redwood.
Discord, Coinbase, Twitch, Chess.com, Plaid, and test provider.
To add a new provider, simply create a new file in the providers directory.
- Authorization Code Grant Type with supoort for OAuth2.1 including PKCE
- All providers can be used for Authentication (logins) or Authorization (user data)
- Web-side redirection UI
- No 3rd-party services required, and only one external dependency (pkce-challenge)
Current discussion here in the Redwood Community Forum.
https://oauth2-client-redwood-eta.vercel.app/login (please let me know if it doesn't work, Supabase pauses the database when not in use)
NOTE: after authentication, there's a bug where the the redirect to profile page may fail, and it appears to ask you to log in again. Simply navigate to /profile to see the user's data.
Test credentials for node-oidc-provider: [email protected]
password can be anything.
NOTE: if you're using a provider only for authorization, skip to step 3.
- Setup dbAuth
yarn rw setup auth dbAuth
No need to follow the all instructions there, instead you will update the graphql schema as defined in step 3.
Also, create the session secret in your .env
using yarn rw g secret
SESSION_SECRET=abc123
- Install necessary dependencies
cd api && yarn add pkce-challenge
- Update the schema as necessary
Include any additional data from the provider you want to store in your database. For example, if you want to store the user's Twitch username, you can add it to the User model.
model User {
id String @id
username String? @unique
address String? @unique
email String? @unique
// --------------- STATE --------------
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
refreshToken String?
accessToken String?
OAuth OAuth[]
betaAccess Boolean @default(false)
}
model OAuth {
state String @id
codeChallenge String
codeVerifier String
createdAt DateTime @default(now())
user User? @relation(fields: [userId], references: [id])
userId String?
}
- Modify the provider files
In api/src/lib/auth/providers/
, you'll find a files for each provider. You can copy one as a template for a new provider. Each provider has the following functions:
// This is where your backend exchanges the grant for a access token from provider. Each provider has slightly different requirements, so be sure to ensure this is correct.
export const onSubmitCode = async (code, { memberId }) => {
const body = {
grant_type: 'authorization_code',
client_id: process.env.COINBASE_CLIENT_ID,
client_secret: process.env.COINBASE_CLIENT_SECRET,
redirect_uri: COINBASE_REDIRECT_URI,
code,
}
const encodedBody = encodeBody(body)
const response = await fetch(COINBASE_OAUTH_URL_TOKEN, {
method: 'post',
body: encodedBody,
//...
}
// This is the logic you want to process after a user is connected to the provider.
export const onConnected = async ({ accessToken, refreshToken, memberId }) => {
const userDetails = await fetch('https://api.coinbase.com/v2/user', {
headers: {
Authorization: `Bearer ${accessToken}`,
'CB-VERSION': '2022-11-22',
},
}).then((res) => {
if (res.status != 200)
throw 'Coinbase authorization failed, or secret invalid'
return res.json()
})
const user await db.user.create({
// ...
// NOTE: you may need to modify return value here:
// For authentication use-cases, it should return the user object.
// For authorization it can simply return `{ status: 'SUCCESS' }`.
return user
Here are the current providers available, and they can each be modified to fit your needs.
- Discord (PKCE req.): Create a user with their Discord profile, email, handle, and avatar for creating a user.
- Chess.com: Create a user with their Chess.com profile, email, handle, and avatar for creating a user.
- Keyp (in development): Create a new user with their wallet address.
- Node OIDC (PKCE req.): A demo provider using node-oidc-provider. I am hosting this for the demo, or you can run it locally yourself (repo here)
Note if you are using a provider for authentication, you will need add it to the web redirection provider so that the appropriate query is made upon redirection back to the app.
- Coinbase: Grab their ethereum deposit address.
- Twitch: Grab their Twitch username.
- Plaid: Grab their Plaid link_token to use with an approved app. (Plaid is evil and you should avoid using them)
- Cleanup tasks
If you created a new provider, be sure its exported properly in api/src/lib/auth/providers/index.js
.
If you're using a provider for Authenticaion, you will need to do the following:
- Add the provider as an option in
api/src/lib/auth/validation.js
- Add the provider as an option to
SigninPage.js
andAPPROVED_LOGIN_PROVIDERS
inweb/src/providers/redirection/redirection.js
- Add revokation feature to frontend
- Publish client as package
oauth2-client-redwood
, and allow easily configuring new clients. - Add more providers, and have them working in the demo (your help needed!)
- Simplify code (maybe make it a package?) and improve documentation
- Improve the UI
- Fix redirect bug to /profile
- Security audit
To run this repo locally:
- Update your .env from
.env.example
. There are two test servers included.
- OAuth 2.0 https://oauth.net/2/
- OAuth Server libraries: https://oauth.net/code/nodejs/
- oidc-client-ts https://github.com/authts/oidc-client-ts
- oauth4webapi https://github.com/panva/oauth4webapi
- openid-client https://github.com/panva/node-openid-client
- node-oidc-provider https://github.com/panva/node-oidc-provider
- https://authguidance.com/
Improve onboarding and payments in your games & web3 apps effortlessly with OAuth logins for wallets and debit card transactions. Create a Keyp account; it's free!
Copyright © 2023 Nifty Chess, Inc.
This project is MIT licensed.