I'm really new with Node JS and now I'm learning about how to use JWT Authentication in my Rest API
I already make token generator in my login function but when I try to verify the token with setting up some role where if the role equal 2 I could get a data. And now I having trouble because I can't verify my token
Log in:
exports.login = function(req, res){
var post = {
email : req.body.email,
password : req.body.password
}
var query = "SELECT * FROM ?? WHERE ?? = ? AND ?? = ?";
var table = ["user", "password", md5(post.password), "email",post.email];
query = mysql.format(query,table);
connection.query(query, function(error, rows){
if(error){
console.log(error);
}else{
if (rows.length == 1){
//ini 1440 dalam second
var token = jwt.sign({rows}, config.secret);
id_user = rows[0].id;
username = rows[0].username;
email = rows[0].email;
tanggal_daftar = rows[0].tanggal_daftar;
role = rows[0].role;
var data = {
id_user : id_user,
access_token : token,
username : username,
email : email,
tanggal_daftar : tanggal_daftar,
role : role,
ip_address : ip.address()
}
res.json({
success : true,
message : "Token JWT generate",
token : token,
idUser: data.id_user,
username : username,
email : data.email,
tanggal_daftar : tanggal_daftar,
role : data.role
});
}else{
res.json({"Error": true, "Message":"Email atau password anda salah"});
}
}
});
}
Token check:
const jwt = require('jsonwebtoken');
const config = require('../config/secret');
function verifikasi(role){
return function (req, rest, next){
// var role = req.body.role;
//cek authorization header
var tokenWithBearer = req.headers.authorization;
if(tokenWithBearer){
var token = tokenWithBearer.split(' ')[1];
//verifikasi
jwt.verify(token, config.secret, function(err, decoded){
if(err){
return rest.status(401).send({auth:false, message:"Token tidak terdaftar!"});
}else{
if(role == 2){
req.auth = decoded;
next();
}else{
return rest.status(401).send({auth:false, message:"gagal melakukan otorisasi!"});
}
}
});
}else{
return rest.status(401).send({auth:false, message:"Token tidak tersedia!"});
}
}
}
module.exports = verifikasi;
Index:
// alamat dengan otoritas khusus
router.get('/api/v1/rahasia', verifikasi(), auth.halamanrahasia);
There's an error in your if(role == 2) you should change it to (decoded.role == 2)
Edit: change if(role == 2) to if(decoded.rows.role == 2)
Related
This is the code for login authorization
exports.login = catchAsync(async(req, res, next) => {
// const { email, password } = req.body;
const email = req.body.email;
const password = req.body.password;
// 1. check if the email and password exist
if (!email || !password) {
return next(new AppError('please provide password or email!', 400));
}
// 2. check if the email and password are corrects
const user = await User.findOne({ email }).select('+password');
const correct = await user.correctPassword(password,user.password);
if (!user || !correct) {
return next(new AppError('please enter valid email or password', 401));
}
// 3. if all ok, send token to client
const token = '';
res.status(200).json({
status: 'sucess',
token,
user,
});
});
the code is looking correct!
assigning null to the user after await findone query
I am making a project where I am facing this error. What I wanted to do is that according to the condition it should redirect the server to the particular routes but getting this error.
routes.post("/check", (req, res) => {
console.log("/check");
// console.log(req.body);
username = req.body.username;
password = req.body.password;
console.log("Step 1");
console.log("Username:", username, "\n", "Password", password);
console.log(public);
for (let i in public) {
if (username === i && password === public[i]) {
console.log("Authenticated success");
res.redirect("/public");
} else {
res.redirect("/404");
}
}
res.redirect("/public");
});
Output is
/check
Step 1
Username: shivam2
Password 4321
{ shivam2: '4321', arjun2: 'dcba' }
Authenticated success
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
You should return in case of successful authentication:
routes.post("/check", (req, res) => {
console.log("/check");
// console.log(req.body);
username = req.body.username;
password = req.body.password;
console.log("Step 1");
console.log("Username:", username, "\n", "Password", password);
console.log(public);
for (let i in public) {
if (username === i && password === public[i]) {
console.log("Authenticated success");
return res.redirect("/public");
}
}
res.redirect("/404");
});
You're calling multiple redirects, one in each iteration of the loop, which causes the error. However, you don't need the loop at all - you can examine public[username] directly (logging removed for brevity's sake):
routes.post("/check", (req, res) => {
username = req.body.username;
password = req.body.password;
if (public[username] === password) {
console.log("Authenticated success");
res.redirect("/public");
} else {
res.redirect("/404");
}
});
I am trying to implement the usage of JWT but it seems that my token is not being stored.
this is the creating of the token...
router.post('/index', async (req, res) => {
let post = { //retreive user input
username: req.body.username,
password: req.body.password,
}
try {
const user = await dbb('users').first('*').where({username: post.username});
if(!user) {
res.render(path.resolve('./myviews/index'), { //display if user is not found
info: 'The Username Or Password You Have Entered Does Not Match Our Records'
});
}
if(user) {
const validPass = await bcrypt.compare(post.password, user.password);
if(validPass){
const token = jwt.sign(`${user}`, process.env.ACCESS_TOKEN);
res.json({token: token});
res.redirect('/home');
} else {
res.render(path.resolve('./myviews/index'), { //display if user is not found
info: 'The Username Or Password You Have Entered Does Not Match Our Records'
});
}
}
} catch(e) {
console.log(e);
}
});
this is the function that is supposed to use the token...
function authToken(req, res, next) {
const authHeader = req.headers['authorization'];
if(typeof authHeader !== 'undefined') {
console.log("here")
const bearer = authHeader.split(' ');
const bearerToken = bearer[1];
req.token = bearerToken;
next();
} else {
res.sendStatus(401);
}
im wondering if anyone can help me understand where i am going wrong
PLEASE SOMEONE
Below is the code for a login app that I was trying out, and as I'm sure you can gather I'm a real noob at this, I think I did everything right because there weren't any errors thrown, but I came across this problem, and its been killing me.
I've been wracking my brain for an answer I just can't get the ejs to render the view. Upon inspecting the network shows the fetch item to be correct but It just doesn't render.
obj.js
const form = document.getElementById('Signinform');
form.addEventListener('submit', Signin);
async function Signin(event){
event.preventDefault();
const email = document.getElementById('email').value
const password = document.getElementById('password').value
const result = await fetch('/user/signin',{
method:'POST',
headers:{
'Content-Type':'application/json',
'Accept': 'text/html'
},
body:JSON.stringify({
email,
password
})
})//.then((res)=>res.json())
//console.log(result)
};
User.js
const express = require('express');
const router =express.Router();
//mongodb user model
const user = require('./../models/user');
const bodyParser = require('body-parser');
//password handler
const bcrypt = require('bcrypt');
//making the router use request body as json
//Signup
router.post('/signup',(req,res)=>{
let{name, email, password, dateofBirth} = req.body;
name = name.trim();
email = email.trim();
password = password.trim();
dateofBirth = dateofBirth.trim();
if(name == "" || email == "" || password == "" || dateofBirth == ""){
res.json({
status:"FAILED",
message:"Empty input fields"
});
}else if(!/^[a-zA-Z]*$/.test(name)) {
res.json({
status:"FAILED",
message:"Invalid name entered"
});
}else if(!/^[\w-\.]+#([\w-]+\.)+[\w-]{2,4}$/.test(email)){
res.json({
status:"FAILED",
message:"Invalid name entered"
});
}else if(! new Date(dateofBirth).getTime()){
res.json({
status:"FAILED",
message:"Invalid date of Birth entered"
});
}else if(password.length < 8){
res.json({
status:"FAILED",
message:"Password is too short!!"
})
}else{
//Checking if user already exists
user.find({email}).then(result=>{
if (result.length){
//if user already exists
res.json({
status: "FAILED",
message: "User with the provided email still exists"
})
} else{
//Try to create a new user
//password handling
const saltRounds =10;
bcrypt.hash(password,saltRounds).then(hashedPassword =>{
const newUser = new user({
name,
email,
password:hashedPassword,
dateofBirth
});
newUser.save().then(result=>{
res.json({
status: "SUCCESS",
message:"Signup succesful",
data:result,
})
}).catch(err=>{
res.json({
status:"FAILED",
message:"An error occured while trying to save User"
})
})
}).catch(err=>{
res.json({
status:"FAILED",
message:"An error occured while hashing password!"
})
})
}
}).catch(err=>{
console.log(err);
res.json({
status:"FAILED",
message:"An error occurered while checking for existing user"
})
})
}
})
//Rendering Sign in page
router.get('/signin',async(req,res)=>{
res.render('user_signin');
});
//Signin
router.post('/signin', async(req,res)=>{
let{email, password}=req.body;
email = email.trim();
password = password.trim();
if(email == "" || password == ""){
res.json({
status:"FAILED",
message:"Empty Credentials supplied"
});
}else{
//Check if user exists
user.find({email})
.then(data =>{
if(data.length){
//user exists
const hashedPassword = data[0].password;
bcrypt.compare(password,hashedPassword).then(result=>{
if(result){
//password matches
// res.json({
// status:"SUCCESS",
// message:"Signin succesful",
// data : data
// });
res.render('signinsuccess',{name : data[0].name});
}else{
res.json({
status: "FAILED",
message: "Invalid password entered"
});
}
})
.catch(err=>{
res.json({
status: "FAILED",
message:"An error occured while comparing passwords"
})
})
}else{
res.json({
status:"FAILED",
message:"Invalid Credentials entered"
})
}
})
.catch(err=>{
res.json({
status:"FAILED",
message:"An error occured while checking for existing user"
})
})
}
})
module.exports = router;
server.js
var express = require('express');
//getting database
require('./config/db.js');
const app = require('express')();
const port = 3000;
app.set('view engine','ejs');
const UserRouter =require('./api/user');
app.use('/assets', express.static('assets'));
//For accepting post form data
const bodyparser = require('express').json;
app.use(bodyparser());
app.use('/user', UserRouter)
app.listen(port,()=>{
console.log(`Server running on port ${port}`);
})
PLEASE HELP
I am building an app using the MEAN stack and I'm fairly new to it. My current issue is that I am trying to reference my Surf Model to a User Model in express. What I want it to do is simply create a new Surf Object with a reference to the user that created it. My current set up spits out an error when I try to create a new Surf object on a POST request. By the way I am also using jsonwebtokens for authentication. Not sure if that has anything to do with it, but just mentioning it. Any help is appreciated.
/models/surf.js
// surf.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//SURF SCHEMA
// ============================================
var SurfSchema = new Schema({
title: String,
longitude: Number,
latitude: Number,
comment: String,
created: { type: Date, default: Date.now },
user_id: {type: Schema.ObjectId, ref: 'User'}
});
var Surf = mongoose.model('Surf', SurfSchema);
module.exports = Surf;
/models/user.js
//USER MODEL
// Require packages for User model
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var bcrypt = require('bcrypt-nodejs');
//USER SCHEMA
// ============================================
var UserSchema = new Schema({
name: String,
username: {type: String, required: true, index: {unique: true}},//No duplicate usernames
password: {type: String, required: true, select: false}//Do not return password
});
//HASH PASSWORD
// ============================================
//Hash password before saving
UserSchema.pre('save', function(next){
var user = this;
//Hash password only if the password has been changed or is new
if(!user.isModified('password')) return next();
//Generate Salt
bcrypt.hash(user.password,null, null, function(err,hash){
if(err) return next(err);
//Change the password to the hash version
user.password = hash;
next();
});
});
//Create method to compare a given password with the database hash
UserSchema.methods.comparePassword = function(password){
var user = this;
return bcrypt.compareSync(password,user.password);
};
//Create User model out of userSchema
var User = mongoose.model('User', UserSchema);
module.exports = User;
/routes/api.js
//api.js
var bodyParser = require('body-parser');
var User = require('../models/user');
var Surf = require('../models/surf');
var jwt = require('jsonwebtoken');
var config = require('../config');
//superSecret secret for creating tokens
var superSecret = config.secret;
//Pass in app and express to use express object for express.Router()
module.exports = function(app, express){
// Instance of express Router
var apiRouter = express.Router();
//API AUTHENTICATE ROUTE
// ====================================================================
//Route for authenticating user at /api/authenticate
apiRouter.post('/authenticate', function(req, res){
//find the user and select username and password explicitly
User.findOne({
username: req.body.username
}).select('name username password').exec(function(err, user){
if(err) throw err;
// no user with that username was found
if(!user){
res.json({success: false, message: 'Authentication failed. User not found'});
}else if (user) {
//check if password is a match
var validPassword = user.comparePassword(req.body.password);
if(!validPassword) {
res.json({success: false, message: 'Authentication failed. Wrong password'});
}else {
//if user is found and password matches
var token = jwt.sign({
name: user.name,
username: user.username
}, superSecret, {
expiresInMinutes: 1440 //Expires in 24 hours
});
//return the information including token as json
res.json({
success: true,
message: 'Here is your token',
token: token
});//End response json
}
}
});
});//End Post authenticate
//TOKEN MIDDLEWARE
// ====================================
//Middleware to use before for all requests(Token varification)
apiRouter.use(function(req,res,next){
//logging
console.log('A visitor has arrived');
//Check Header OR Url parameters OR POST parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
//Decode the token
if(token){
//Verifies secret and checks expiration
jwt.verify(token, superSecret, function(err, decoded){
if(err){
return res.json({success: false, message: 'Failed token authentication'});
}else {
//If token checks out, save the request to be used in other routes
req.decoded = decoded;
next();//User may continue forward if they have a valid token
}
});
}else {
//if there is no token return 403(access forbidden) and an error message
return res.status(403).send({success: false, message: 'No token Provided'});
}
});//End Middleware
//TEST ROUTE
// ====================================
//Test Route
apiRouter.get('/', function(req,res){
res.json({message: "Welcome to the API"});
});
//API ROUTES USERS
// ====================================================================
//routes that end with /users --------------------
apiRouter.route('/users')
//CREATE a user on /api/users
.post(function(req, res){
//creat a new user instance from User model
var user = new User();
//set the users information that comes from requests
user.name = req.body.name;
user.username = req.body.username;
user.password = req.body.password;
//save user and check for errors
user.save(function(err){
if(err){
//A duplicate was entered
if(err.code == 11000){
return res.json({success: false, message: 'A user with that username exists'});
}else {
return res.send(err);
}
}
res.json({message: 'User created!'});
});//End save
})//End Post
//GET all users at /api/users
.get(function(req, res){
User.find(function(err,users){
if(err){
res.send(err);
}
//Return all users
res.json(users);
});
});//End Get
//routes that end with /users:user_id --------------------
apiRouter.route('/users/:user_id')
//GET a single user at /users/:user_id
.get(function(req,res){
User.findById(req.params.user_id, function(err,user){
if(err) res.send(err);
// return the user
res.json(user);
});
})//End Get
//UPDATE the user with this id at /users/:user_id
.put(function(req,res){
//use user model to find the user we want
User.findById(req.params.user_id, function(err,user){
if(err) res.send(err);
//update the users info only if it is new(no blanks)
if(req.body.name) user.name = req.body.name;
if(req.body.username) user.username = req.body.username;
if(req.body.password) user.password = req.body.password;
//save user
user.save(function(err){
if(err) res.send(err);
// return message
res.json({message: 'User has been updated!'});
});//End save
});//End find by id
})//End Post
//DELETE a user with this id at /users/:user_id
.delete(function(req,res){
User.remove({
_id: req.params.user_id
}, function(err, user){
if(err) res. send(err);
res.json({message: 'Succesfully deleted user'});
});
});
//api endpoint to get user information
apiRouter.get('/me', function(req, res){
res.send(req.decoded);
});
//API ROUTES SURF
// ====================================================================
//routes that end with /surf --------------------
apiRouter.route('/surf')
//CREATE a surf on /api/surf
.post(function(req, res){
//create a new instance of the surf model
var surf = new Surf();
User.findOne({username: decoded.username}, function(err, user){
req.user = user;
next()
})
//set the surf information that comes from requests
surf.title = req.body.title;
surf.longitude = req.body.longitude;
surf.latitude = req.body.latitude;
surf.comment = req.body.comment;
surf.user_id = req.user._id;
//save user and check for errors
surf.save(function(err){
if(err)
res.send(err);
res.json({message: 'Surf Session Created!'});
});//End save
})//End Post
//GET all surf sessions at api/surf
.get(function(req, res){
// Use the Surf model to find all surf sessions
Surf.find({ }, function(err, surfSesh) {
if (err)
res.send(err);
res.json(surfSesh);
});
})//
return apiRouter;
};
I tried surf.user_id = req.user._id;
but I keep getting an error of cannot
read property '_id of undefined'
In this else block right here:
}else {
//If token checks out, save the request to be used in other routes
req.decoded = decoded;
next();//User may continue forward if they have a valid token
}
You have a decoded token, which means you should have access to the username. What you then have to do is get the user model, and set it to the req object, and only afterwards call next() e.g.
User.findOne({username: decoded.username}, function(err, user){
req.user = user;
next()
})
---EDIT----
//TOKEN MIDDLEWARE
// ====================================
//Middleware to use before for all requests(Token varification)
apiRouter.use(function(req,res,next){
//logging
console.log('A visitor has arrived');
//Check Header OR Url parameters OR POST parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
//Decode the token
if(token){
//Verifies secret and checks expiration
jwt.verify(token, superSecret, function(err, decoded){
if(err){
return res.json({success: false, message: 'Failed token authentication'});
}else {
//If token checks out, save the request to be used in other routes
req.decoded = decoded;
// GET USER HERE
User.findOne({username: decoded.username}, function(err, user){
req.user = user;
next()
})
}
});
}else {
//if there is no token return 403(access forbidden) and an error message
return res.status(403).send({success: false, message: 'No token Provided'});
}
});//End Middleware