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

推荐订阅源

WordPress大学
WordPress大学
MyScale Blog
MyScale Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
人人都是产品经理
人人都是产品经理
C
Check Point Blog
宝玉的分享
宝玉的分享
B
Blog RSS Feed
博客园 - 三生石上(FineUI控件)
量子位
Martin Fowler
Martin Fowler
酷 壳 – CoolShell
酷 壳 – CoolShell
Jina AI
Jina AI
IT之家
IT之家
阮一峰的网络日志
阮一峰的网络日志
博客园 - 叶小钗
J
Java Code Geeks
The Cloudflare Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
腾讯CDC
P
Proofpoint News Feed
美团技术团队
H
Help Net Security
B
Blog
博客园_首页

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;

}

}