Node.js 如何和Passport实现ACL

Node.js 如何和Passport实现ACL

Node.js 是一个异步事件驱动的JavaScript运行时环境,设计用于构建可扩展的网络应用程序。

Passportjs: 是Node.js的身份验证中间件。非常灵活和模块化,可以轻松地集成到任何基于Express的Web应用程序中。它提供了一套全面的策略,支持使用用户名和密码、Facebook、Twitter等进行身份验证。开发人员广泛使用它来创建安全且可扩展的Web应用程序。

使用Node.js实现Passport的ACL步骤:

步骤1: 在任何IDE中创建一个带有项目名称的文件夹(我使用的是VS Code)。请查看下面的文件夹结构。

步骤1: 打开终端并输入“npm init”。按下回车键使用默认值,因为此命令用于设置新的npm包。安装成功后,它将创建一个package.json文件夹。

步骤2: 按下“npm i express ejs”以安装node依赖项。

步骤3: 按下“npm i –save-dev nodemon dotenv”以安装开发环境依赖项。Nodemon允许在任何更改时自动重启服务器,dotenv允许我们使用.env文件存储环境变量,并加载到服务器。

步骤4: 根据以下目录结构制作“.env”和“.gitignore”文件。

Node.js 如何和Passport实现ACL

.gitignore包含了那些我们不想提交到Git仓库的文件。在这里,我们存储了.env和node_modules,因为它们只包含依赖项,且.env可能包含我们不想与世界共享的敏感信息。

Node.js 如何和Passport实现ACL

步骤5: 我们最后需要做的是设置package.json,以便我们可以启动服务器。按照以下方式编辑脚本部分:

Node.js 如何和Passport实现ACL

步骤6: 现在,在终端中按下“npm run devStart”将启动服务器。您应该在终端中得到类似这样的输出。

Node.js 如何和Passport实现ACL

2: 在 server.js 中使用以下代码设置我们的基本 express 应用程序。

// STEP 1: Install all the necessary dependencies  
// add the dependencies with the help of require 
  
const express = require('express') 
const app = express() 
  
// To run our app on port 3000 
app.listen(3000)

但是,如果我们在编写这段代码后运行我们的服务器,我们将在localhost:300上获得以下页面。

Node.js 如何和Passport实现ACL

它显示了“无法GET /”,因为我们尚未为应用程序设置任何路由。让我们在第3步中解决这个问题。

3: 在server.js中添加上述代码,并创建一个名为views的文件夹,其中包含index.ejs文件。

Node.js 如何和Passport实现ACL

4:使用“npm i bcrypt”安装另一个包: bcrypt将允许我们对密码进行哈希处理,并比较哈希后的密码,确保我们的应用程序完全安全。

server.js

// Requiring all the necessary dependencies 
const express = require('express') 
const app = express() 
const bcrpyt = require('bcrypt') 
  
const users = [] 
  
// In order to use ejs set up view-engine 
app.set('view-engine', 'ejs') 
app.use(express.urlencoded({ extended: false })) 
  
// Setting up home-page route 
app.get('/', (req, res) => { 
    res.render('index.ejs', { name: 'Janhvi' }) 
}) 
  
// Set up login page route 
app.get('/login', (req, res) => { 
    res.render('login.ejs') 
}) 
  
// Set up register page route 
app.get('/register', (req, res) => { 
    res.render('register.ejs') 
}) 
  
app.post('/register', async (req, res) => { 
      
    // Using try catch block in order to  
    // resolve errors 
    try { 
          
        // Hashing password with bcrypt 
        const hashedPassword =  
            await bcrpyt.hash(req.body.password, 10) 
        users.push({ 
            id: Date.now().toString(), 
            name: req.body.name, 
            email: req.body.email, 
            password: hashedPassword 
        }) 
        res.redirect('/login') 
    } catch { 
        res.redirect('/register') 
    } 
    console.log(users) 
}) 
  
// To run our app on port 3000 
app.listen(3000)

login.ejs

<!-- login page --> 
<h1>Login</h1> 
  
<!-- Make a simple login form with name, email  
    and password fields make a submit button  
    at end --> 
<form action="/login" method="POST"> 
    <div> 
        <label for="name">Name</label> 
        <input type="text" id="name" 
            name="name" required> 
    </div> 
    <div> 
        <label for="email">Email</label> 
        <input type="email" id="email" 
            name="email" required> 
    </div> 
    <div> 
        <label for="password">Password</label> 
        <input type="password" 
            id="password" name="password" required> 
    </div> 
    <button type="submit">Login</button> 
</form> 
<a href="/register">Register</a>

register.ejs

<!-- Register page  --> 
<h1>Register</h1> 
  
<!-- Make a simple register form with 
    name, email and password fields 
    make a submit button at end --> 
<form action="/register" method="POST"> 
    <div> 
        <label for="name">Name</label> 
        <input type="text" id="name" 
            name="name" required> 
    </div> 
    <div> 
        <label for="email">Email</label> 
        <input type="email" id="email" 
            name="email" required> 
    </div> 
    <div> 
        <label for="password">Password</label> 
        <input type="password" id="password" 
            name="password" required> 
    </div> 
    <button type="submit">Register</button> 
</form> 
<a href="/login">Login</a>

在http://localhost:3000/login上期望的输出

Node.js 如何和Passport实现ACL

http://localhost:3000/register

Node.js 如何和Passport实现ACL

在输入后,控制台的密码将显示为哈希值

Node.js 如何和Passport实现ACL

5:使用“npm i passport passport-local express-session express-flash”安装passportjs。

在文件“passport-config.js”中存储所有与Passport相关的信息。现在让我们来看一下具有所需逻辑的所有代码的最终版本。

server.js

// The below code is only suitable for  
// development not suitable for production 
if (process.env.NODE_ENV !== 'production') { 
    require('dotenv').config() 
} 
  
// Requiring all the necessary dependencies 
const express = require('express') 
const app = express() 
const bcrypt = require('bcrypt') 
const passport = require('passport') 
const flash = require('express-flash') 
const session = require('express-session') 
const methodOverride = require('method-override') 
  
const initializePassport = require('./passport-config') 
initializePassport( 
    passport, 
    email => users.find(user => user.email === email), 
    id => users.find(user => user.id === id) 
) 
  
const users = [] 
  
// Setting up the view-engine in order  
// to use ejs in code further 
app.set('view-engine', 'ejs') 
app.use(express.urlencoded({ extended: false })) 
app.use(flash()) 
app.use(session({ 
    secret: process.env.SESSION_SECRET, 
    resave: false, 
    saveUninitialized: false
})) 
app.use(passport.initialize()) 
app.use(passport.session()) 
app.use(methodOverride('_method')) 
  
// Setting up route logic for home page 
app.get('/', checkAuthenticated, (req, res) => { 
    res.render('index.ejs', { name: req.user.name }) 
}) 
  
// Setting up route logic for login page 
app.get('/login', checkNotAuthenticated, (req, res) => { 
    res.render('login.ejs') 
}) 
  
app.post('/login', checkNotAuthenticated,  
passport.authenticate('local', { 
    successRedirect: '/', 
    failureRedirect: '/login', 
    failureFlash: true
})) 
  
app.get('/register', checkNotAuthenticated,  
(req, res) => { 
    res.render('register.ejs') 
}) 
  
// Hashinhg the passwords for each user  
// using bcrypt 
app.post('/register', checkNotAuthenticated,  
async (req, res) => { 
    try { 
        const hashedPassword =  
            await bcrypt.hash(req.body.password, 10) 
        users.push({ 
            id: Date.now().toString(), 
            name: req.body.name, 
            email: req.body.email, 
            password: hashedPassword 
        }) 
        res.redirect('/login') 
    } catch { 
        res.redirect('/register') 
    } 
}) 
  
// To to login page upon pressing the 
// logout button 
app.delete('/logout', (req, res) => { 
    req.logOut() 
    res.redirect('/login') 
}) 
  
// If user is authenticated redirect to  
// next page otherwise redirect to login 
// page 
function checkAuthenticated(req, res, next) { 
    if (req.isAuthenticated()) { 
        return next() 
    } 
    res.redirect('/login') 
} 
  
function checkNotAuthenticated(req, res, next) { 
    if (req.isAuthenticated()) { 
        return res.redirect('/') 
    } 
    next() 
} 
  
// To run our app on port 3000 
app.listen(3000)

passport-config.js

// Requiring all the necessary dependencies 
const LocalStrategy = require('passport-local').Strategy 
const bcrypt = require('bcrypt') 
  
// Add all the code related to passportjs to 
// the main initialize function 
function initialize(passport, getUserByEmail, getUserById) { 
    const authenticateUser = async (email, password, done) => { 
        const user = getUserByEmail(email) 
  
        // If user is null return output  
        // "no user with that email" 
        if (user == null) { 
            return done(null, false,  
                { message: 'No user with that email' }) 
        } 
  
        // try-catch block to check for correct password 
        try { 
            if (await bcrypt.compare(password, user.password)) { 
                return done(null, user) 
            } else { 
                return done(null, false,  
                    { message: 'Password incorrect' }) 
            } 
        } catch (e) { 
            return done(e) 
        } 
    } 
  
    passport.use(new LocalStrategy( 
        { usernameField: 'email' }, authenticateUser)) 
    passport.serializeUser((user, done) => done(null, user.id)) 
    passport.deserializeUser((id, done) => { 
        return done(null, getUserById(id)) 
    }) 
} 
  
// Exporting the initialize function 
module.exports = initialize

index.ejs

<!-- Index page which will display  
    the Hi user_name -->
<h1>Hi <%= name %></h1> 
  
<!-- Setting up a logout button in  
    order to exit the page -->
<form action="/logout?_method=DELETE" method="POST"> 
  <button type="submit">Log Out</button> 
</form>

login.ejs

<!-- login page -->
<h1>Login</h1> 
  
<!-- Adding embedded javascript code to  
    check for errors -->
<% if (messages.error) { %> 
<%= messages.error %> 
<% } %> 
  
<!-- Make a simple login form with  
    name, email and password fields 
    make a submit button at the end -->
<form action="/login" method="POST"> 
    <div> 
        <label for="email">Email</label> 
            <input type="email" id="email" 
            name="email" required> 
    </div> 
    <div> 
        <label for="password">Password</label> 
        <input type="password" 
            id="password" name="password" required> 
    </div> 
    <button type="submit">Login</button> 
</form> 
  
<a href="/register">Register</a>

register.ejs

<!-- Register page -->
<h1>Register</h1> 
  
<!-- Make a simple register form with  
    name, email and password fields 
    make a submit button at the end -->
<form action="/register" method="POST"> 
    <div> 
        <label for="name">Name</label> 
        <input type="text" id="name" 
            name="name" required> 
    </div> 
    <div> 
        <label for="email">Email</label> 
        <input type="email" id="email" 
            name="email" required> 
    </div> 
    <div> 
        <label for="password">Password</label> 
        <input type="password" id="password" 
            name="password" required> 
    </div> 
    <button type="submit">Register</button> 
</form> 
<a href="/login">Login</a>

6:使用“npm i method-override”安装另一个包- 其余的代码保持不变。

启动服务器后将出现的第一个页面是登录页面。

Node.js 如何和Passport实现ACL

如果您已经注册过,请使用相同的电子邮件和密码登录。

Node.js 如何和Passport实现ACL

如果您尚未注册并且尝试登录,则将获得以下结果。

Node.js 如何和Passport实现ACL

首先注册自己,记住邮箱和密码,然后再试着登录。

Node.js 如何和Passport实现ACL

成功注册和登录后,您将在您的页面上看到以下内容:“欢迎来到GeeksforGeeks your_name”。

Node.js 如何和Passport实现ACL

输出:

Node.js 如何和Passport实现ACL

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程