Node.js express中的身份认证的实现

yizhihongxing

Node.js express中的身份认证是Web应用开发中非常重要的一环。以下是实现身份认证的完整攻略:

Step1:安装相关模块

首先安装以下模块:

  • express-session:用于维持用户的会话状态
  • passport:提供了运用于Node.js的身份验证中间件
  • passport-local:用于基于用户名和密码的身份验证策略
  • bcryptjs:用于加密用户密码

安装命令为:

npm install express-session passport passport-local bcryptjs

Step2:配置中间件

在创建Express应用程序的过程中,需要将以上安装的模块作为中间件使用,并指定相应的配置选项,例如:

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

// 配置 express 中间件
app.use(session({
    secret: 'secret-key',
    resave: false,
    saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());

// 配置本地身份验证策略
passport.use(new LocalStrategy(
    function(username, password, done) {
        // 在这里查询数据库,验证用户身份
        User.findOne({ username: username }, function(err, user) {
            if (err) { return done(err); }
            if (!user) { return done(null, false, { message: 'Incorrect username.' }); }
            if (!bcrypt.compareSync(password, user.password)) { return done(null, false, { message: 'Incorrect password.' }); }
            return done(null, user);
        });
    }
));

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

passport.deserializeUser(function(id, done) {
    User.findById(id, function(err, user) {
        done(err, user);
    });
});

在这个示例中,我们配置了一个本地身份验证策略,该策略使用了bcrypt.js密码加密算法来对用户密码进行加密,然后与数据库中的加密密码进行比较以验证用户身份。我们还实现了用户对象的序列化和反序列化,以便将用户保存在会话中。

Step3:编写登录和注册路由

在实现中间件后,需要编写登录和注册路由:

// 登录页面
app.get('/login', function(req, res) {
    res.render('login');
});

app.post('/login', passport.authenticate('local', { failureRedirect: '/login' }), function(req, res) {
    res.redirect('/');
});

// 注册页面
app.get('/register', function(req, res) {
    res.render('register');
});

app.post('/register', function(req, res) {
    const { username, password } = req.body;
    const hash = bcrypt.hashSync(password, 10);
    const newUser = new User({ username, password: hash });
    newUser.save(function(err) {
        if (err) {
            console.log(err);
            res.redirect('/register');
        } else {
            res.redirect('/login');
        }
    });
});

在这个示例中,我们为登录和注册分别编写了get和post路由。对于登录路由,我们使用了passport.authenticate中间件来进行身份验证,并指定了验证策略为本地验证策略。对于注册路由,我们使用bcrypt.hashSync函数对用户密码进行加密,并将加密后的密码保存到数据库中。

Step4:编写路由保护中间件

编写路由保护中间件是实现身份认证的一部分,它将确保被保护的路由只有在用户已登录的情况下才能访问。以下是一个示例:

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

app.get('/', ensureAuthenticated, function(req, res) {
    res.render('index', { user: req.user });
});

在这个示例中,我们定义了一个中间件函数ensureAuthenticated,该函数将检查用户是否已被验证通过(即已经登录)。如果用户已经登录,它将继续执行下一步,否则将用户重定向到登录页面。

Step5:编写用户注销路由

最后,需要实现用户注销,以便用户能够结束会话并从会话中删除存储的用户对象。以下是一个示例:

app.get('/logout', function(req, res) {
    req.logout();
    res.redirect('/login');
});

在这个示例中,我们使用req.logout()函数来将用户的会话状态设置为未验证,并将用户重定向到登录页。

通过上面的步骤,我们完成了一个基础的身份认证系统。

示例说明:

下面给出两个示例,分别说明了在实现身份认证过程中使用的具体技术和方法。

示例1:使用JWT进行身份认证

在实现身份认证过程中,可以使用JSON Web Token(JWT)来生成和验证身份认证令牌。在这个示例中,我们使用jsonwebtoken模块来实现JWT身份认证。以下是示例代码:

const jwt = require('jsonwebtoken');

// 生成token
app.post('/login', function(req, res) {
    const { username, password } = req.body;
    if (username === 'admin' && password === 'admin') {
        const token = jwt.sign({ username }, 'secret-key');
        res.json({ token });
    } else {
        res.status(401).json({ message: 'Username or password incorrect' });
    }
});

// 验证token
function verifyToken(req, res, next) {
    const bearerHeader = req.headers['authorization'];
    if (typeof bearerHeader !== 'undefined') {
        const bearerToken = bearerHeader.split(' ')[1];
        req.token = bearerToken;
        jwt.verify(req.token, 'secret-key', function(err, decoded) {
            if (!err) {
                req.user = decoded;
                next();
            } else {
                res.sendStatus(403);
            }
        });
    } else {
        res.sendStatus(403);
    }
}

app.post('/protected', verifyToken, function(req, res) {
    res.json({ message: 'Access granted', user: req.user });
});

在这个示例中,我们定义了如下路由:

  • /login:用于生成JWT令牌和验证用户的登录凭证。
  • /protected:需要通过Token验证身份才能访问的加密路由。

/login路由中,我们使用jwt.sign()来生成一个包含用户名的令牌,然后将其作为JSON响应返回给客户端。在/protected路由中,我们使用verifyToken中间件来验证请求中是否包含正确的Token。如果Token是有效的,我们将请求持有的用户名附加到响应中,向用户显示已通过身份验证。

示例2:使用Passport-local-mongoose进行身份认证

Passport-local-mongoose是Passport.js中间件的一个功能强大的扩展,它简化了用户身份认证的代码实现。该库提供了一种轻松的方式在Mongoose模型上构建本地Passport.js身份验证。以下是示例代码:

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const User = require('./models/user');
const mongoose = require('mongoose');
const passportLocalMongoose = require('passport-local-mongoose');

const mongoURI = 'mongodb://localhost:27017/db';
mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true });

// 在用户模型中使用Passport-local-mongoose插件
User.plugin(passportLocalMongoose, {
    usernameField: 'email'
});

// 配置本地身份验证策略
passport.use(new LocalStrategy({ usernameField: 'email' }, User.authenticate()));

// 用于序列化和反序列化用户对象
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

在这个示例中,我们使用Mongoose来连接MongoDB数据库,并使用了passportLocalMongoose插件。该插件为我们提供了新的模型方法User.authenticate(),它自动在用户和密码字段上进行身份验证。我们还实现了用户对象的序列化和反序列化,类似于上一步中的做法。

通过这个示例,我们可以看出使用Passport-local-mongoose可以大大简化身份认证的代码实现,帮助减轻开发人员的工作负担。

总结:

身份认证是Web应用开发的重要组成部分,我们可以使用第三方模块和插件来实现符合标准的身份验证流程,减轻开发人员的工作量。目前,市场上有大量的身份认证解决方案以及现成的身份认证插件和模块可供选择,在实现身份认证过程中可以根据具体应用场景和需求选择合适的技术方案。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Node.js express中的身份认证的实现 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • node中Express 动态设置端口的方法

    设置Express应用程序的端口是一个很常见的需求,可以通过以下两种方式实现动态设置端口: 1. 通过环境变量 可以通过设置环境变量来动态地设置Express应用程序的端口。这在使用Docker或类似的环境时非常有用,因为容器端口通常是动态分配的。 首先在应用程序中读取环境变量: const port = process.env.PORT || 3000; …

    node js 2023年6月8日
    00
  • node.js核心模块有哪些

    当我们使用 Node.js 来进行开发时,核心模块是不可或缺的。Node.js 的核心模块是指 Node.js 官方实现的模块,它们与 Node.js 运行时相关联,可以在 Node.js 环境中随时使用。以下是 Node.js 的核心模块: fs 模块 fs 模块是一个处理文件系统的模块,它提供了文件的读写、拷贝、删除、移动等功能。下面是一个使用 fs 模…

    node js 2023年6月7日
    00
  • Angularjs—项目搭建图文教程

    AngularJS 项目搭建图文教程 AngularJS 是一款流行的前端 JavaScript 框架,它可以帮助开发者快速构建单页应用程序。本文将演示如何在自己的电脑上搭建 AngularJS 项目的环境并进行开发。 1. 安装 Node.js Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。安装了 Node.js,…

    node js 2023年6月8日
    00
  • nodejs中exports与module.exports的区别详细介绍

    在nodejs中,我们可以通过exports与module.exports暴露模块成员,但它们之间存在一些差异。下面我们来详细介绍它们的区别。 module.exports与exports的关系 在nodejs中,每个模块都有一个module对象,它代表当前模块,其中包含了exports属性,而exports是module.exports的一个别名。也就是说…

    node js 2023年6月8日
    00
  • node.js Sequelize实现单实例字段或批量自增、自减

    Node.js Sequelize是一个基于Javascript的ORM框架,可以轻松地对SQL数据库进行操作。实现自增、自减功能可以通过在模型中定义自增、自减字段,在增加或减少时更新字段值即可。以下是实现“单实例字段自增、自减”的攻略。 单实例字段自增 步骤一:在模型中定义自增字段 通过Sequelize定义模型时,可以添加自增属性。例如,一个用户模型中i…

    node js 2023年6月8日
    00
  • 理解JavaScript中window对象的一些用途

    理解JavaScript中window对象的一些用途 简介 Window 对象是JavaScript中的顶层对象,它代表了浏览器中打开的窗口或者标签页。浏览器中打开的每一个窗口/标签页都会有一个对应的 Window 对象。在浏览器中,全局作用域的 this 就是指向 Window 对象。 用途 1. 窗口大小和位置 使用 window 对象,我们可以获取浏览…

    node js 2023年6月8日
    00
  • window.location.reload 刷新使用分析(去对话框)

    当我们需要刷新网页时,可以使用 JavaScript 中的 window.location.reload() 方法。该方法会重新加载当前页面,从而达到刷新的效果。 使用该方法时,可以选择是否清除浏览器缓存的内容。如果不清除缓存,则页面仅会重新加载服务器上的内容,而不会重新获取所有文件;但如果选择清除缓存,则浏览器会重新获取所有文件,可以获取最新的内容。 下面…

    node js 2023年6月8日
    00
  • node.js实现多图片上传实例

    具体的攻略如下: 1. 安装依赖 在开始项目前,需要先安装所需的依赖: npm install express multer 其中,express是Node.js的Web框架,用于创建服务器;multer是Node.js的一个中间件,用于处理HTTP上传请求,支持多文件上传。 2. 编写HTML页面 需要先编写一个HTML页面,用于展示表单和上传控件。以下为…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部