使用 MongoDB、bcrypt 和带有 cookie 的 JWT web 令牌在 Node.js 中进行身份验证🍪。

2025-06-07

使用 MongoDB、bcrypt 和带有 cookie 的 JWT web 令牌在 Node.js 中进行身份验证🍪。

向应用程序添加身份验证是最具挑战性的任务之一😖,但对于开发人员来说也是非常重要的部分,但今天我将教你🥰如何做到这一点,来吧,今天只需 10 分钟⚡,就和我一起制作一个身份验证页面。

1.让我们初始化 npm 并安装我们将要使用的所有必要包。



npm init -y
npm i express bcryptjs body-parser dotenv ejs jsonwebtoken mongoose cookie-parser


Enter fullscreen mode Exit fullscreen mode

2.现在创建 2 个目录 views 和 public,并创建 server.js 文件,现在您的文件夹结构应该如下所示👇。

图像

3.现在将软件包包含在你的 server.js 中并创建一个 express 服务器

在本文中,我们包含了配置整个旅程中所需的所有软件包和所需代码🤠。



const express = require('express');
const bodyparser=require("body-parser");
const mongoose= require('mongoose');
const jwt = require('jsonwebtoken');
var cookieParser = require('cookie-parser');
const port = process.env.PORT || 3000;
const app = express();
require('dotenv').config();
const bcrypt = require('bcryptjs');
const salt = 10;
app.set('view engine', 'ejs');
app.use(bodyparser.urlencoded({extended:true}));
app.use(express.json());
app.use(cookieParser());
app.use(express.static("public"));
app.listen(port,()=>{
    console.log(`Running on port ${port}`);
})


Enter fullscreen mode Exit fullscreen mode

4.现在在views文件夹中创建3个文件👇。

图像

5.现在让我们创建登录注册和受保护的页面。



// signin.ejs
<form action="/login" method="post">
<label for="">Email</label>
<input type="email" name="email" id="">
<label for="">Password</label>
<input type="text" name="password" id="">
<button type="submit">SignIN</button>
</form>
<form action="/signup" method="get">
<button type="submit">
    Do not have an account
</button>
</form>


Enter fullscreen mode Exit fullscreen mode


// signup.ejs
<form action="/signup" method="post">
<label for="">Email</label>
<input type="email" name="email" id="">
<label for="">Password</label>
<input type="text" name="password" id="">
<button type="submit">SignUP</button>
</form>


Enter fullscreen mode Exit fullscreen mode


//home.ejs
This is the protected page


Enter fullscreen mode Exit fullscreen mode

6.现在我们将创建我们的.env 文件并存储我们的 JWT 密钥和 mongodb 连接 url 并添加到我们的服务器。

图像



// get our urls and secrets
const JWT_SECRET=process.env.jwt;
const MONGODB_URL=process.env.mongodb;

// making connnection with our database
mongoose.connect(MONGODB_URL, {useFindAndModify: false,useNewUrlParser: true, useUnifiedTopology: true,useCreateIndex: true});


Enter fullscreen mode Exit fullscreen mode

现在您的服务器应该看起来像这样👇。



const express = require('express');
const bodyparser=require("body-parser");
const mongoose= require('mongoose');
const jwt = require('jsonwebtoken');
var cookieParser = require('cookie-parser');
const port = process.env.PORT || 3000;
const app = express();
require('dotenv').config();
const bcrypt = require('bcryptjs');
const salt = 10;
app.set('view engine', 'ejs');
app.use(bodyparser.urlencoded({extended:true}));
app.use(express.json());
app.use(cookieParser());
app.use(express.static("public"));

// get our urls and secrets
const JWT_SECRET=process.env.jwt;
const MONGODB_URL=process.env.mongodb;

// making connnection with our database
mongoose.connect(MONGODB_URL, {useFindAndModify: false,useNewUrlParser: true, useUnifiedTopology: true,useCreateIndex: true});



app.listen(port,()=>{
    console.log(`Running on port ${port}`);
})


Enter fullscreen mode Exit fullscreen mode

7.现在我们将创建用户身份验证的架构和注册方法。



// Schema For User Auth
const userSchema = new mongoose.Schema({
    email:{type:String,required:true,unique:true},
    password:{type:String,required:true}
},{collection:'users'}
const User= mongoose.model("User",userSchema);
)


Enter fullscreen mode Exit fullscreen mode


app.post('/signup',async (req,res)=>{
    // geting our data from frontend
    const {email,password:plainTextPassword}=req.body;
    // encrypting our password to store in database
    const password = await bcrypt.hash(plainTextPassword,salt);
    try {
        // storing our user data into database
        const response = await User.create({
            email,
            password
        })
        return res.redirect('/');
    } catch (error) {
        console.log(JSON.stringify(error));
        if(error.code === 11000){
            return res.send({status:'error',error:'email already exists'})
        }
        throw error
    }
})


Enter fullscreen mode Exit fullscreen mode

8.现在我们将创建我们的登录方法,我们将使用 JWT 创建一个身份验证令牌并将其作为 cookie 存储在我们的浏览器中



// user login function
const verifyUserLogin = async (email,password)=>{
    try {
        const user = await User.findOne({email}).lean()
        if(!user){
            return {status:'error',error:'user not found'}
        }
        if(await bcrypt.compare(password,user.password)){
            // creating a JWT token
            token = jwt.sign({id:user._id,username:user.email,type:'user'},JWT_SECRET,{ expiresIn: '2h'})
            return {status:'ok',data:token}
        }
        return {status:'error',error:'invalid password'}
    } catch (error) {
        console.log(error);
        return {status:'error',error:'timed out'}
    }
}

// login 
app.post('/login',async(req,res)=>{
    const {email,password}=req.body;
    // we made a function to verify our user login
    const response = await verifyUserLogin(email,password);
    if(response.status==='ok'){
        // storing our JWT web token as a cookie in our browser
        res.cookie('token',token,{ maxAge: 2 * 60 * 60 * 1000, httpOnly: true });  // maxAge: 2 hours
        res.redirect('/');
    }else{
        res.json(response);
    }
})


Enter fullscreen mode Exit fullscreen mode

9.最后,我们将为剩余的页面创建路由,并检查进入受保护页面的授权



const verifyToken = (token)=>{
    try {
        const verify = jwt.verify(token,JWT_SECRET);
        if(verify.type==='user'){return true;}
        else{return false};
    } catch (error) {
        console.log(JSON.stringify(error),"error");
        return false;
    }
}



// get requests
app.get('/',(req,res)=>{
    const {token}=req.cookies;
    if(verifyToken(token)){
        return res.render('home');
    }else{
        res.redirect('/login')
    }
})

app.get('/login',(req,res)=>{
    res.render('signin');
})

app.get('/signup',(req,res)=>{
    res.render('signup')
})


app.listen(port,()=>{
    console.log(`Running on port ${port}`);
})


Enter fullscreen mode Exit fullscreen mode

10.最后,您的 server.js 应该看起来像这样👇。



const express = require('express');
const bodyparser=require("body-parser");
const mongoose= require('mongoose');
const jwt = require('jsonwebtoken');
var cookieParser = require('cookie-parser');
const port = process.env.PORT || 3000;
const app = express();
require('dotenv').config();
const bcrypt = require('bcryptjs');
const salt = 10;
app.set('view engine', 'ejs');
app.use(bodyparser.urlencoded({extended:true}));
app.use(express.json());
app.use(cookieParser());
app.use(express.static("public"));

// get our urls and secrets
const JWT_SECRET=process.env.jwt;
const MONGODB_URL=process.env.mongodb;

// making connnection with our database
mongoose.connect(MONGODB_URL, {useFindAndModify: false,useNewUrlParser: true, useUnifiedTopology: true,useCreateIndex: true});

// Schema For User Auth
const userSchema = new mongoose.Schema({
    email:{type:String,required:true,unique:true},
    password:{type:String,required:true}
},{collection:'users'}
)
const User= mongoose.model("User",userSchema);

app.post('/signup',async (req,res)=>{
    // geting our data from frontend
    const {email,password:plainTextPassword}=req.body;
    // encrypting our password to store in database
    const password = await bcrypt.hash(plainTextPassword,salt);
    try {
        // storing our user data into database
        const response = await User.create({
            email,
            password
        })
        return res.redirect('/');
    } catch (error) {
        console.log(JSON.stringify(error));
        if(error.code === 11000){
            return res.send({status:'error',error:'email already exists'})
        }
        throw error
    }
})


// user login function
const verifyUserLogin = async (email,password)=>{
    try {
        const user = await User.findOne({email}).lean()
        if(!user){
            return {status:'error',error:'user not found'}
        }
        if(await bcrypt.compare(password,user.password)){
            // creating a JWT token
            token = jwt.sign({id:user._id,username:user.email,type:'user'},JWT_SECRET,{ expiresIn: '2h'})
            return {status:'ok',data:token}
        }
        return {status:'error',error:'invalid password'}
    } catch (error) {
        console.log(error);
        return {status:'error',error:'timed out'}
    }
}

// login 
app.post('/login',async(req,res)=>{
    const {email,password}=req.body;
    // we made a function to verify our user login
    const response = await verifyUserLogin(email,password);
    if(response.status==='ok'){
        // storing our JWT web token as a cookie in our browser
        res.cookie('token',token,{ maxAge: 2 * 60 * 60 * 1000, httpOnly: true });  // maxAge: 2 hours
        res.redirect('/');
    }else{
        res.json(response);
    }
})

const verifyToken = (token)=>{
    try {
        const verify = jwt.verify(token,JWT_SECRET);
        if(verify.type==='user'){return true;}
        else{return false};
    } catch (error) {
        console.log(JSON.stringify(error),"error");
        return false;
    }
}



// get requests
app.get('/',(req,res)=>{
    const {token}=req.cookies;
    if(verifyToken(token)){
        return res.render('home');
    }else{
        res.redirect('/login')
    }
})

app.get('/login',(req,res)=>{
    res.render('signin');
})

app.get('/signup',(req,res)=>{
    res.render('signup')
})


app.listen(port,()=>{
    console.log(`Running on port ${port}`);
})


Enter fullscreen mode Exit fullscreen mode

太好了!!您已成功在您的网站中添加身份验证🥳🥳🥳🥳。

在 Twitter 上联系我:-
https://twitter.com/nyctonio

请查看我的 Github 获取源代码:https: //github.com/nyctonio/jwtauth

文章来源:https://dev.to/nyctonio/authentication-in-node-js-with-mongodb-bcrypt-and-jwt-web-tokens-with-cookies-hl3
PREV
如何在没有太多设计背景的情况下构建产品名称生成徽标生成图标动画/插图排版结论
NEXT
使用 React 和 Django 构建完整的仓库管理系统。