Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

With oauth2 #4

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

With oauth2 #4

wants to merge 4 commits into from

Conversation

clxrityy
Copy link

nextjs-discord-bot (with oauth2)

Overview

Accessing the designated root url (/) will require authentication with Discord. Upon authorizing, the user will be
redirected back to the root url (with additional user details displayed)

ex. with authorization


Replication

OAuth2 URLs

  • Generate your own OAuth2 redirect URI with every additional scope needed
    (discord.com/applications/CLIENT_ID/oauth2)

    • The path should be /api/auth/discord/redirect

      select redirect uri

  • Add these urls (development and production) to config.ts:

    export const CONFIG = {
      REDIRECT_URI:
        process.env.NODE_ENV === "development"
          ? "http://localhost:3000/api/auth/discord/redirect"
          : "https://yourdomain.com/api/auth/discord/redirect", // REPLACE WITH YOUR DOMAIN
      OAUTH2_INVITE_URL: process.env.NODE_ENV === "development" ? "" : "", // (copy the generated url)
      ROOT_URL: process.env.NODE_ENV === "development" ? "http://localhost:3000" : "", // REPLACE WITH YOUR DOMAIN
    }

Discord endpoints

  • After making a POST request to Discord's oauth token endpoint
    (discord.com/api/v10/oauth2/token)
    • The access_token from the data given is used to receive the Discord user's details by making a GET request to
      the discord.com/api/v10users/@me endpoint:
      export async function getUserDetails(accessToken: string) {
        return await axios.get<OAuth2UserResponse>(CONFIG.OAUTH2_USER, {
          headers: {
            Authorization: `Bearer ${accessToken}`,
          },
        })
      }

Vercel Postgres / Prisma

I've implemented a prisma table which will store the encrypted access & refresh token from the user data. This can be used later, but for now has minimal impact on the application.

Getting Started with Vercel Postgres

Prisma is used to store the User model:

model User {
  id           String @id @default(uuid())
  userId       String @unique
  accessToken  String @unique
  refreshToken String @unique
}

Quickstart

Create a postgres database on your vercel dashboard

  • This will automatically generate the necessary environment variables for the database.

Retreive the environment variables locally:

vercel env pull .env.development.local

Generate the prisma client:

npx prisma generate

Create the table(s) in your database based on your prisma schema:

npx prisma db push
  • The build script within package.json has been altered to support the prisma database in production:
    "build": "prisma generate && next build"

Encryption

crypto-js is used to encrypt the access_token & refresh_token before storing into the User model.

import CryptoJS from 'crypto-js';

export const encryptToken = (token: string) => CryptoJS.AES.encrypt(token, process.env.ENCRYPTION_KEY);
  • Add a custom ENCRYPTION_KEY environment variable (make sure to also add this to your vercel project environment variables)

Cookies & JWT

jsonwebtoken & cookie are used for signing & serializing the cookie for the user session.

  • Add a custom JWT_SECRET environment variable (make sure to also add this to your vercel project environment variables)
import { CONFIG } from "@/config";
import { serialize } from "cookie";
import { sign } from "jsonwebtoken";
import { cookies } from "next/headers";

const token = sign(user.data, process.env.JWT_SECRET, {
    expiresIn: "24h"
});

cookies().set(CONFIG.cookieName, serialize(CONFIG.cookieName, token, {
    httpOnly: true,
    secure: process.env.NODE_ENV === "production",
    sameSite: "lax",
    path: "/"
}))

Updates

  • The .env.local.example has been updated to include:
# discord.com/developers/applications/APP_ID/oauth2
DISCORD_CLIENT_SECRET=

# Encryption: a custom secret key for encrypting sensitive data
# This is used to encrypt the user's Discord token in the database
# If you don't set this, the app will use a default key
ENCRYPTION_KEY=

# JWT for cookies
# This is used to sign the JWT token for the user's session
# If you don't set this, the app will use a default key
JWT_SECRET=

# Prisma / Postgres
# These are used to connect to the database
# See here: https://vercel.com/docs/storage/vercel-postgres/quickstart
POSTGRES_DATABASE=
POSTGRES_HOST=
POSTGRES_PASSWORD=
POSTGRES_PRISMA_URL=
POSTGRES_URL=
POSTGRES_URL_NON_POOLING=
POSTGRES_URL_NO_SSL=
  • An additional config.ts has been made to include necesssary authentication URLs

Copy link

vercel bot commented Jun 10, 2024

@clxrityy is attempting to deploy a commit to the Jeff's projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant