virtualcommons / port-of-mars

Port of Mars is an online, game-based, social science experiment set on the first human community on the Red Planet. We are now in an open beta where anyone aged 18 and over can participate.
https://portofmars.asu.edu
GNU Affero General Public License v3.0
10 stars 16 forks source link

authentication stopgap integration w/ nuxt + client + server #806

Closed alee closed 11 months ago

alee commented 2 years ago

Eventually the nuxt app may subsume and contain all of what used to be server and client but this is a long-range task that will require extensive refactoring of all the components etc., to use tailwindcss and nuxt abstractions and simplifications

So as a stopgap measure one direction we're exploring uses JWT tokens based on this SO question:

https://stackoverflow.com/questions/73398610/nuxt-3-jwt-authentication-using-fetch-and-pinia

and in particular this question: https://stackoverflow.com/a/73406144/93370

  1. create an api login post endpoint in nuxt (/server/api/login.post.ts) that creates a fresh JWT based on an email address, e.g.,
import jwt from 'jsonwebtoken';

export default defineEventHandler(async (event) => {
  const body = await useBody(event);
  const token: string = await jwt.sign({ email: body.email }, email_hash);
  return token;
});
  1. set the JWT into an httponly cookie

https://stackoverflow.com/questions/39810741/how-to-store-a-jwt-token-inside-an-http-only-cookie

  1. add a nuxt middleware (server/middleware/setAuth.ts) that makes accessing the authenticated user in all other api endpoints easier:
import jwt from 'jsonwebtoken';

    export default defineEventHandler(async (event) => {
      if (event.req.headers.authentication) {
        event.context.auth = { email: await jwt.verify(event.req.headers.authentication, email_hash).email };
      }
    });
  1. all requests that require authentication need to include the JWT in the headers under an authentication key
$fetch('/api/dashboard', {
            method: 'post',
            headers: {
              authentication: myJsonWebToken,
            },
          });
  1. in all nuxt server endpoints that need an auth user get it via event.context.auth.email or whatever we set it to in the server/middleware

  2. legacy server side also needs these same checks, this is probably gonna be ugly copy/paste duplication for simplicity at the moment

alee commented 11 months ago

closing for now until we decide on #795