lucia-auth / examples

A collection of example projects built with Lucia
MIT License
168 stars 40 forks source link

remix guide missing? #17

Open deadcoder0904 opened 5 months ago

deadcoder0904 commented 5 months ago

switched from next.js to remix so curious.

any reason for that? does remix not gel well with lucia or is remix-auth recommended?

pilcrowOnPaper commented 5 months ago

I'm waiting for Remix to implement middleware first since the loader pattern on its own isn't well suited for auth

deadcoder0904 commented 5 months ago

cool. it is in the planned phase so might take like 6 months to come.

remix does have some auth libraries to use like remix-auth or good ol' session based auth which i'm using for now.

pilcrowOnPaper commented 5 months ago

Lucia does work with Remix right now. It's just not as good as I want it to be. And the issues aren't specific to Lucia either

chetannn commented 4 months ago

This is how I am doing. Lucia with Remix middleware would be awesome. auth.server.ts

import { redirect } from "@remix-run/node";
import { Argon2id as Argon2idOslo } from "oslo/password";
import { Lucia } from "lucia";
import { DrizzlePostgreSQLAdapter } from "@lucia-auth/adapter-drizzle";
import { db } from "./drizzle/config.server";
import {
  users as usersTable,
  sessions as sessionsTable,
} from "./drizzle/schema.server";

const adapter = new DrizzlePostgreSQLAdapter(db, sessionsTable, usersTable);

export const Argon2id = Argon2idOslo;

export const lucia = new Lucia(adapter, {
  sessionCookie: {
    attributes: {
      // set to `true` when using HTTPS
      secure: process.env.NODE_ENV === "production",
    },
  },
  getUserAttributes: (attributes) => {
    return {
      email: attributes.email,
    };
  },
});

declare module "lucia" {
  interface Register {
    Lucia: typeof lucia;
    DatabaseUserAttributes: {
      email: string;
    };
  }
}

export const getSession = async (request: Request) => {
  const cookie = request.headers.get("Cookie");

  const sessionId = lucia.readSessionCookie(cookie ?? "");

  if (!sessionId) {
    return null;
  }

  return lucia.validateSession(sessionId);
};

export const redirectIfAuthenticated = async (
  request: Request,
  redirectTo: string = "/dashboard"
) => {
  const session = await getSession(request);

  if (session) {
    return redirect(redirectTo);
  }
};

export const verifyPassword = async (
  hashedPassword: string,
  password: string
) => {
  return new Argon2id().verify(hashedPassword, password);
};

export const login = async (
  userId: string,
  redirectTo: string = "/dashboard"
) => {
  const session = await lucia.createSession(userId, {});

  const sessionCookie = lucia.createSessionCookie(session.id);

  return redirect(redirectTo, {
    headers: {
      "Set-Cookie": sessionCookie.serialize(),
    },
  });
};

export const logout = async (
  request: Request,
  redirectTo: string = "/login"
) => {
  const cookie = request.headers.get("Cookie");

  const sessionId = lucia.readSessionCookie(cookie ?? "");

  if (!sessionId) {
    return redirect(redirectTo);
  }

  await lucia.invalidateSession(sessionId);
  const sessionCookie = lucia.createBlankSessionCookie();

  return redirect(redirectTo, {
    status: 302,
    headers: {
      "Set-Cookie": sessionCookie.serialize(),
    },
  });
};