Reputation: 65
I'm trying to authenticate on the Backend so that only the right user can get the correct data.
App.js
const express = require('express');
const app = express();
const {mongoose} = require('./db/mongoose');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken')
//load Middleware
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
//CORS Middleware
app.use(function(req, res, next) {
req.header("Content-Type: application/x-www-form-urlencoded");
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", " GET, POST, OPTIONS, PUT, PATCH, DELETE")
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, x-access-token, x-refresh-token");
res.header(
'Access-Control-Expose-Headers',
'x-access-token, x-refresh-token'
);
next();
})
To fulfil my goals I create the authenticate method
//aunthenticate middleware
let authenticate = (res, req, next) => {
let token = res.header('x-access-token');
jwt.verify(token, User.getJWTSecret(), (err, decoded) => {
if (err) {
res.status(401).send(err);
console.log(err)
} else {
req.user_id = decoded._id;
next();
}
})
}
I had to get in the user Model
const { User } = require('./db/models/users.model');
The point is every user should have a record of its own dispatch. Hence
app.get('/dispatch', authenticate, (req, res) => {
Dispatch.find({
_userId: req.user_id
}).then((dispatch) => {
res.send(dispatch);
}).catch((e) => {
res.send(e);
})
})
All the hints we have are in the
Users.model.js
const mongoose = require("mongoose");
const _ = require("lodash");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
const crypto = require("crypto")
const jwtSecret = "XXXXXXXXXXX";
const UserSchema = new mongoose.Schema({
email: {
type: String,
required: true,
minlength: 1,
trim: true,
unique: true
},
password: {
type: String,
required: true,
minlength: 8
},
sessions: [{
token: {
type: String,
required: true
},
expiresAt: {
type: Number,
required: true
}
}]
});
//Model Methods
UserSchema.statics.getJWTSecret = () => {
return jwtSecret;
}
const User = mongoose.model('User', UserSchema);
module.exports = { User };
When I run the get dispatch method is postman the error on my terminal is jsonwebtokenError: jwt must be a string
Upvotes: 5
Views: 14621
Reputation: 1
When you take out your token from the cookies that full object is giving you you need to take the token from the cookies. This error came to me also if you want you can use this method because yours and my code are a bit different you need to take only token from the header and not the whole object and your jwt_secret also be string
Upvotes: 0
Reputation: 1768
As the error suggests, your problem stands on how you set your token, as the value you are providing doesn't seem to be of string type.
Now I can't see where you set your token with the code you shared, but to fix the issue you will just need to make sure you pass a stringified value.
I'd suggest you force it by using toString
:
jwt.sign(jwtValue.toString(), jwtSecret, { expiresIn: '1800s' });
Or you can stringify if you want to store objects:
jwt.sign(JSON.stringify(jwtValue), jwtSecret, { expiresIn: '1800s' });
Upvotes: 4