如何将jwt令牌发送到node.js中的受保护路由

Mah*_*eva 4 node.js express jwt

我创建了一个登录表单,如果用户输入正确的密码和用户名,该表单应将用户重定向到仪表板页面。如果用户尝试在未登录的情况下导航到仪表板 URL,则该页面不应显示,因为它是受保护的路由。我试图在用户登录时发送 jwt 令牌,但这不起作用,我在登录时只收到 Forbidden 消息,因此令牌似乎未正确发送,如何发送 jwt 令牌并访问用户登录成功后的受保护路由?

这是我的 server.js:

const express = require('express');
const jwt = require('jsonwebtoken');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
let Post = require('./models/post.model.js');
const app = express();
const cors = require('cors');
require('dotenv').config();

app.use(cors());
app.use("/assets", express.static(__dirname + "/assets"));
app.use(bodyParser.urlencoded({ extended: true }));
const BASE_URL = process.env.BASE_URL;

const PORT = process.env.PORT || 1337;
mongoose.connect(BASE_URL, { useNewUrlParser: true, useUnifiedTopology: true })

const connection = mongoose.connection;

connection.once('open', function () {
    console.log('Connection to MongoDB established succesfully!');
});

app.set('view-engine', 'ejs');

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

app.post('/', (req, res) => {
    let username = req.body.username;
    let password = req.body.password;

    const user = {
        username: username,
        password: password
    }

    jwt.sign({ user }, process.env.SECRET_KEY, (err, token) => {
        res.json({
            token
        })
    });

    if (username !== process.env.USER_NAME && password !== process.env.USER_PASSWORD) {
        res.json('Invalid credentials');
    } else {
        res.setHeader('Authorization', 'Bearer '+ token);
        res.redirect('/dashboard')
    }

});

app.get('/dashboard', verifyToken, (req, res) => {
    jwt.verify(req.token, process.env.SECRET_KEY, (err, authData) => {
        if (err) {
            res.sendStatus(403);
        } else {
            res.sendStatus(200);
        }
    });
    res.render('dashboard.ejs');
});

app.get('/dashboard/createPost', verifyToken, (req, res) => {
    res.render('post.ejs');
});

app.post('/dashboard/createPost', async (req, res) => {
    let collection = connection.collection(process.env.POSTS_WITH_TAGS);
    res.setHeader('Content-Type', 'application/json');
    let post = new Post(req.body);
    collection.insertOne(post)
        .then(post => {
            res.redirect('/dashboard')
        })
        .catch(err => {
            res.status(400).send(err);
        });
});

// TOKEN FORMAT
// Authorization: Bearer <access_token>

//Verifing the Token
function verifyToken(req, res, next) {
    // Get auth header value
    const bearerHeader = req.headers['authorization'];
    // Check if bearer is undefined
    if (typeof bearerHeader !== 'undefined') {
        // Spliting the bearer
        const bearer = bearerHeader.split(' ');
        // Get token from array
        const bearerToken = bearer[1];
        // Set the token
        req.token = bearerToken;
        // Next middleware
        next();

    } else {
        // Forbid the route
        res.sendStatus(403);
    }

}

app.listen(PORT);
Run Code Online (Sandbox Code Playgroud)

Tah*_*ahi 7

看这个例子,我使用中间件(checkAuthLogin),此代码包含您问题的所有内容:

索引.js:

const express = require('express');
const app = express();
require('./db/mongoose');

const userRouter = require('./routers/user');


app.use(express.json());
app.use(userRouter);


app.listen(3000, ()=> { 
    console.log('Server is up on port ', 3000)
});
Run Code Online (Sandbox Code Playgroud)

db/mongoose.js:

const mongoose = require('mongoose');

mongoose.connect("mongodb://127.0.0.1:27017/db-test" {
    useNewUrlParser : true,
    useCreateIndex : true,
    useFindAndModify : false,
    useUnifiedTopology: true
});
Run Code Online (Sandbox Code Playgroud)

路由器/user.js:

const express = require('express');
const router = new express.Router();
const RootUser = require('../models/root-user');
const {checkRootLogin} = require('../middleware/checkAuthLogin');

router.post('/createrootuser', async (req, res) => {

    const updates = Object.keys(req.body);
    const allowedUpdatesArray = ['name', 'password'];
    const isValidOperation = updates.every((update) => allowedUpdatesArray.includes(update));

    if (!isValidOperation) {
        return res.status(400).send({error: 'Invalid Request Body'})
    }

    const rootUser = new RootUser(req.body);

    try {
        await rootUser.save();
        // sendWelcomeEmail(user.email, user.name)
        const token = await rootUser.generateAuthToken();
        //console.log(user)
        res.status(201).send({rootUser, token});
    } catch (e) {
        res.status(400).send(e)
    }

});

//use this middleware(checkRootLogin) for check root user can access this function
router.post('/rootconfig', checkRootLogin, async (req, res) => {

        res.status(200).send({success: 'success add root config'})

});

module.exports = router;
Run Code Online (Sandbox Code Playgroud)

模型/root-user.js:

const mongoose = require('mongoose');
const validator = require('validator');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');    

const userRootSchema = new mongoose.Schema({
    name: {
        type : String,
        required: true,
        unique : true,
        trim : true,
        lowercase : true,
    },
    password: {
        type : String,
        required: true,
        unique : true,
        trim : true,
        lowercase : true,
        minlength : 6,
        validate (value) {
            //if (validator.contains(value.toLowerCase(), 'password')){
            if (value.toLowerCase().includes('password')){
                throw new Error('Password can not contained "password"')
            }
        }
    },

    tokens : [{
        token : {
            type : String ,
            required : true
        }
    }],

}, {
    timestamps: true
});


userRootSchema.methods.generateAuthToken = async function(){

    const root = this;
    // generate token
    try {
        // const token = jwt.sign({ _id : user._id.toString()}, process.env.JWT_SECRET);
        const token = jwt.sign({ _id : root._id.toString()}, "test");
        // add token to user model
        root.tokens = root.tokens.concat({ token });
        await root.save();
        return token
    } catch (e){
        throw new Error(e)
    }

};



userRootSchema.pre('save', async function(next){
    // this give ccess to individual user
    const user = this;

    if (user.isModified('password')){
        user.password = await bcrypt.hash(user.password, 8)
    }
    next()

});

const UserRoot = mongoose.model('UserRoot', userRootSchema);

module.exports = UserRoot;
Run Code Online (Sandbox Code Playgroud)

中间件/checkAuthLogin.js:

const jwt = require('jsonwebtoken');
const RootUser = require('../models/root-user');  

const checkRootLogin = async (req, res, next) => {
    try {
        const token = req.header('Authorization').replace('Bearer ', '');
        // const decoded = jwt.verify(token, process.env.JWT_SECRET);
        const decoded = jwt.verify(token, "test");

        const rootUser = await RootUser.findOne({_id: decoded._id, 'tokens.token': token});

        if (!rootUser) {
            throw new Error("User cannot find!!");
        }

        req.token = token;
        req.rootUser = rootUser;
        req.userID = rootUser._id;
        next()
    } catch (e) {
        res.status(401).send({error: 'Authentication problem!!'})
    }
};

module.exports = {checkRootLogin};
Run Code Online (Sandbox Code Playgroud)