Code Monkey home page Code Monkey logo

how-to-roll-your-own-auth-benawad-discord's Introduction

How to roll your own auth

This repo is a companion to this YouTube video: https://youtu.be/CcrgG5MjGOk

  1. Discord OAUTH with passport.js
passport.use(
    new Strategy(
      {
        clientId: process.env.DISCORD_CLIENT_ID!,
        clientSecret: process.env.DISCORD_SECRET_ID!,
        callbackUrl: `${process.env.API_URL}/auth/discord/callback`,
        scope: ["identify"],
      },

      async (_accessToken, _refreshToken, profile, done) => {
        // 1. grab id
        const discordId = profile._json.id as string;

        // 2. db lookup
        let user = await db.query.users.findFirst({
          where: eq(usersTable.discordId, discordId),
        });

        // 3. create user if not exists
        if (!user) {
          [user] = await db
            .insert(usersTable)
            .values({
              discordId,
            })
            .returning();
        }

        // 4. return user
        done(null, user);
      }
    ) as any
  );
  1. JWTs
const createAuthTokens = (
  user: DbUser
): { refreshToken: string; accessToken: string } => {
  const refreshToken = jwt.sign(
    { userId: user.id, refreshTokenVersion: user.refreshTokenVersion },
    process.env.REFRESH_TOKEN_SECRET!,
    {
      expiresIn: "30d",
    }
  );

  const accessToken = jwt.sign(
    { userId: user.id },
    process.env.ACCESS_TOKEN_SECRET!,
    {
      expiresIn: "15min",
    }
  );

  return { refreshToken, accessToken };
};
  1. Cookies
// __prod__ is a boolean that is true when the NODE_ENV is "production"
const cookieOpts = {
  httpOnly: true,
  secure: __prod__,
  sameSite: "lax",
  path: "/",
  domain: __prod__ ? `.${process.env.DOMAIN}` : "",
  maxAge: 1000 * 60 * 60 * 24 * 365 * 10, // 10 year
} as const;

export const sendAuthCookies = (res: Response, user: DbUser) => {
  const { accessToken, refreshToken } = createAuthTokens(user);
  res.cookie("id", accessToken, cookieOpts);
  res.cookie("rid", refreshToken, cookieOpts);
};

How to deploy server to VPS

Get a VPS like Hostinger if you don't already have one. Use code BENAWAD at checkout for additional savings (SPONSORED)

  1. Save yourself some hassle and setup passwordless ssh into your VPS: https://www.hostinger.com/tutorials/how-to-setup-passwordless-ssh/
  2. Install Dokku on your VPS https://dokku.com/docs/getting-started/installation/ (I like to use this for zero-downtime deployments)
    • The latest version of Ubuntu that Dokku works with is 22.04 (you can change versions in Hostinger's dashboard)
  3. Create an app dokku apps:create api
  4. Create database https://dokku.com/docs/deployment/application-deployment/?h=postgresql#create-the-backing-services
  5. Link database dokku postgres:link pg api
  6. Create Docker image on your computer docker build -t example/auth:1 . --platform=linux
  7. Send Docker image to VPS docker image save example/auth:1 | ssh [email protected] docker load
  8. Tag image in your VPS docker tag example/auth:1 dokku/api:latest
  9. Deploy dokku deploy api latest
    • This will fail
  10. Set environment variables
    dokku config:set api FRONTEND_URL=https://example.com ACCESS_TOKEN_SECRET=hj890duj01jd9012j0dj9021390132 REFRESH_TOKEN_SECRET=q90wej9201je091212903291308 DISCORD_SECRET_ID=asdj902j1d0921 DISCORD_CLIENT_ID=129032180312 DOMAIN=example.com
    • This should redeploy the app and it should work

Custom domain

  1. Setup DNS so your domain points to the VPS
  2. Setup https on your VPS using letsencrypt dokku plugin: https://github.com/dokku/dokku-letsencrypt
    • You will need to set your domain first: dokku domains:set api api.example.com

VPS Security

https://www.hostinger.com/tutorials/vps-security

Frontend deployment

I like to use Cloudflare pages

Debugging cookies

https://github.com/benawad/how-to-debug-cookies

how-to-roll-your-own-auth-benawad-discord's People

Contributors

benawad avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.