惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
V
V2EX
Y
Y Combinator Blog
Jina AI
Jina AI
G
Google Developers Blog
Last Week in AI
Last Week in AI
博客园 - 叶小钗
H
Hackread – Cybersecurity News, Data Breaches, AI and More
L
LangChain Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
V
Visual Studio Blog
aimingoo的专栏
aimingoo的专栏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
The GitHub Blog
The GitHub Blog
D
Docker
量子位
罗磊的独立博客
腾讯CDC

NodeJS Security & NodeJS Secure Coding's Blog

Hardening Your npm and pnpm Configs in the Age of Shai-Hulud Argument Injection vulnerability in git-blame@1.4.0 Argument Injection vulnerability in `gits@0.1.8` Command Injection vulnerability in `@fab1o/git@1.4.0` Command Injection vulnerability in `git-contributors` via unsanitized CLI arguments Command Injection vulnerability in `git-q@0.0.3` Command injection vulnerability via unsanitized CLI arguments in touxing/fast-git-clone Command Injection vulnerability in `willitmerge@0.2.1` A Directory Traversal Vulnerability I found in Mastra AI Frameworks MCP Server Mastering NPX: A Cheatsheet for npm and Node.js Power Users Mitigate Supply Chain Security with DevContainers and 1Password for Node.js Local Development The Tale of the Vulnerable MCP Database Server Bad Security Defaults in Mastra AI Frameworks Templates SQL Injection and Bypassing "Read-Only" Mode in Xata's MCP Server Security Advisory for qix npm supply-chain compromise affecting debug and billions of weekly download users How to Mitigate SQL Bypass in MCP Servers Enhancing MCP Server Security: A Guide to Using execFile Argument Injection Vulnerability in ggit How to Bypass Access Control in PostgreSQL in Simple PSQL MCP Server for SQL Injection Command Injection Flaws in ggit: Unveiling a Vulnerability Command Injection Vulnerability in Create MCP Server STDIO Tool Exposes System Monitoring Functions GitHub Kanban MCP Server Command Injection Vulnerability Threatens Developer Workflows Critical Command Injection Flaw in iOS Simulator MCP Server Exposes Development Environments Command Injection Vulnerability Discovered in Codehooks MCP Server: A Critical Security Analysis SSRF Shenanigans in safe-axios: Redirects Open the Backdoor SSRF Vulnerability in safe-axios: Unintended Public Address Classification Bypassing SSRF Safeguards in ssrfcheck: A Case of Incomplete Denylists Don't Be Fooled by Multicast, SSRF Bypass in private-ip Bypassing SSRF Protection in nossrf: When Your Safeguards Become Loopholes Vue CLI Security Fix to Mitigate NPM Binary Planting
Node.js Authentication from Lucia to Better Auth
2025-04-15 · via NodeJS Security & NodeJS Secure Coding's Blog

Lucia started off as an educational project to teach developers about the fundamental aspects of authentication and authorization. It was created alongside with an implementation guide which then evolved into an official SDK, supporting different database persistency drivers and authentication schemes. However, the maintainer had stepped back from active development and archived the project. What should developers migrate to?

In this article I’ll cover the basics of Lucia authentication in Node.js and JavaScript backends and how to migrate from a Lucia Auth codebase to Better Auth, which is another open-source and well-maintained SDK. $$ $$

Lucia Authentication in Node.js

Lucia started with an auth.js file that exported the database drivers interface and defined the way Lucia manages authentication via session cookie.

The following is a reference file fo how to build a Node.js backend authentication based on SQLite and the BetterSQLite3 database library.

import { Lucia } from "lucia";

import { BetterSqlite3Adapter } from "@lucia-auth/adapter-sqlite";

import { db } from "./db.js";

import type { DatabaseUser } from "./db.js";

const adapter = new BetterSqlite3Adapter(db, {

user: "user",

session: "session"

});

export const lucia = new Lucia(adapter, {

sessionCookie: {

attributes: {

secure: process.env.NODE_ENV === "production"

}

},

getUserAttributes: (attributes) => {

return {

username: attributes.username

};

}

});

declare module "lucia" {

interface Register {

Lucia: typeof lucia;

DatabaseUserAttributes: Omit<DatabaseUser, "id">;

}

}

The Login and Signup workflows used to require specific code to be written that integrates with Lucia. For example, here’s the Lucia code for implementing login:

import { lucia } from "../lib/auth.js";

import type { DatabaseUser } from "../lib/db.js";

export const loginRouter = express.Router();

loginRouter.post("/login", async (req, res) => {

const username: string | null = req.body.username ?? null;

const password: string | null = req.body.password ?? null;

const existingUser = await db().get("SELECT * FROM user WHERE username = ?", username)

if (!existingUser) {

return res.status(400).json({ error: "Invalid username or password" });

}

const validPassword = await verify(existingUser.password_hash, password);

if (!validPassword) {

return res.status(400).json({ error: "Invalid username or password" });

}

const session = await lucia.createSession(existingUser.id, {});

return res.appendHeader("Set-Cookie", lucia.createSessionCookie(session.id).serialize())

.status(200)

.json({

success: true,

})

});

Migrating to Better Auth in Node.js

The version of auth.js in Better Auth exports a similar interface that declares the database driver as well as other authentication information such as CORS if required to be defined (via the trustedOrigins property), the authentication type (in this case it is emailAndPassword) and any plugins we want to connect (in this case, OpenAPI to expose a Swagger like UI that is convenient for development-time).

import { betterAuth } from "better-auth";

import { openAPI } from "better-auth/plugins";

import Database from "better-sqlite3";

export const auth = betterAuth({

database: new Database("./database.db"),

trustedOrigins: [

"http://localhost:3000",

"http://localhost:3005",

],

emailAndPassword: {

enabled: true

},

plugins: [

openAPI(),

]

});

Unlike Lucia, Better Auth manages the Login and other authentication workflows through its own internal middle-ware function for Express and other web application frameworks, so it doesn’t require you to implement it, and instead if exposes an API.

import { db, init } from "./lib/db.js";

import { toNodeHandler } from "better-auth/node";

import { fromNodeHeaders } from "better-auth/node";

import { auth } from "./lib/auth.ts";

// establish a db connection first

await init();

const app = express();

app.all("/api/auth/*", toNodeHandler(auth));

User session data can then be accessed and used as follows in an Express-like middleware function:

res.locals.user = session?.user;

if (session?.user && session?.user?.id) {

const userAttribute = await db().get('SELECT role FROM user_profile WHERE user_id = ?', session.user.id);

if (session?.user?.id && userAttribute?.role === 'admin') {

res.locals.user.isAdmin = true;

}

}