使用 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
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}`);
})
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>
// 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>
//home.ejs
This is the protected page
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});
现在您的服务器应该看起来像这样👇。
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}`);
})
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);
)
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
}
})
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);
}
})
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}`);
})
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}`);
})
太好了!!您已成功在您的网站中添加身份验证🥳🥳🥳🥳。
在 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