Nodejs有类似RoR的devise gem这样的用户认证package么?

Nodejs有类似RoR的devise gem这样的用户认证package么?

RT,感觉写用户系统各种重复劳动啊

4 回复

当然可以。在Node.js生态系统中,确实存在一些类似于Ruby on Rails中的Devise gem的用户认证包。一个非常流行的选择是Passport.js。Passport.js 是一个简单且灵活的身份验证中间件,它支持多种认证策略,如本地用户名/密码、OAuth(包括Facebook、Google等)。

示例代码

首先,你需要安装必要的依赖包:

npm install express passport passport-local bcryptjs

然后,你可以创建一个简单的Express应用,并集成Passport进行用户认证:

1. 初始化项目和安装依赖

// app.js
const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');

const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
    secret: 'secret-key',
    resave: false,
    saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());

// 配置Passport使用LocalStrategy
passport.use(new LocalStrategy(
    function(username, password, done) {
        // 这里应该查询数据库来验证用户名和密码
        const user = { username: 'test', password: bcrypt.hashSync('testpassword', 8) };
        if (username === user.username && bcrypt.compareSync(password, user.password)) {
            return done(null, user);
        } else {
            return done(null, false, { message: 'Invalid credentials.' });
        }
    }
));

// 序列化和反序列化用户
passport.serializeUser(function(user, done) {
    done(null, user.username);
});

passport.deserializeUser(function(username, done) {
    const user = { username: 'test', password: bcrypt.hashSync('testpassword', 8) };
    done(null, user);
});

// 登录路由
app.post('/login', 
    passport.authenticate('local', { failureRedirect: '/login' }),
    function(req, res) {
        res.send('Logged in successfully!');
    }
);

// 注册路由
app.post('/register', async (req, res) => {
    const hashedPassword = await bcrypt.hash(req.body.password, 8);
    // 这里应该将新用户信息保存到数据库
    const newUser = { username: req.body.username, password: hashedPassword };
    res.send('User registered!');
});

// 路由保护
app.get('/', ensureAuthenticated, function(req, res) {
    res.send('Welcome to the protected route.');
});

function ensureAuthenticated(req, res, next) {
    if (req.isAuthenticated()) {
        return next();
    }
    res.redirect('/login');
}

app.listen(3000, () => console.log('Server started on port 3000'));

解释

  • Passport.js 是核心身份验证库。
  • LocalStrategy 提供了本地用户名/密码认证方式。
  • bcryptjs 用于安全地存储密码。
  • ensureAuthenticated 中间件确保只有已登录的用户才能访问特定路由。

这样,你就可以快速搭建一个基本的用户认证系统,而不需要从头开始编写所有逻辑。


有个 passport,但也不是一整套的解决方案

Node.js 社区中有几个用户认证相关的库,可以大大简化用户的认证流程。其中比较流行的包括 Passport.jsExpress.js 结合使用。Passport.js 提供了多种身份验证策略(如本地认证、OAuth、JWT等),并且非常灵活。

以下是一个简单的示例,展示如何使用 Passport.js 实现本地认证。

示例代码

首先安装所需的依赖:

npm install express passport passport-local bcryptjs cookie-parser body-parser express-session

然后创建一个基本的应用程序:

const express = require('express');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');

const app = express();

// 模拟用户数据库
const users = [
    { id: 1, username: 'user', password: bcrypt.hashSync('password', 8) }
];

app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.json());
app.use(express.session({ secret: 'secret' }));
app.use(passport.initialize());
app.use(passport.session());

// 配置本地认证策略
passport.use(new LocalStrategy(
    (username, password, done) => {
        const user = users.find(u => u.username === username);
        if (!user) return done(null, false);
        if (!bcrypt.compareSync(password, user.password)) return done(null, false);
        return done(null, user);
    }
));

passport.serializeUser((user, done) => {
    done(null, user.id);
});

passport.deserializeUser((id, done) => {
    const user = users.find(u => u.id === parseInt(id));
    done(null, user);
});

// 登录路由
app.post('/login', 
    passport.authenticate('local', { failureRedirect: '/login' }),
    (req, res) => {
        res.redirect('/');
    }
);

app.get('/', (req, res) => {
    res.send(req.isAuthenticated() ? 'Logged in' : 'Not logged in');
});

app.listen(3000, () => {
    console.log('Server running on port 3000');
});

解释

  • 安装依赖:我们安装了 expresspassportpassport-localbcryptjs 和会话管理相关的中间件。
  • 配置策略LocalStrategy 用于处理本地认证逻辑。
  • 序列化与反序列化:这些方法用于在会话中存储和恢复用户信息。
  • 登录路由:处理用户的登录请求,如果验证成功,则重定向到首页。

这个例子展示了如何用 Passport.js 实现一个简单的本地认证功能。通过这种方式,你可以避免重复编写用户认证相关的代码,并且可以轻松扩展到其他认证方式。

回到顶部