1

so I have tested my API route /getUser using Postman which is receiving data successfully being received in json format. However the Jwt token which is stored in localstorage and past in the headers is not being verified as within my browser I receive 'Access denied. No JWT provided' which is sent with a 401 status.

Nodejs API is below this includes my authentication route and /getUserwhich users a middleware file found below also which verifies the token

const express = require('express');
const users = express.Router();
const cors = require('cors');
const moment = require('moment');
const jwt = require('jsonwebtoken');
// var exjwt = require('express-jwt');
const auth = require('../middleware/auth');
const bcrypt = require('bcrypt');
const Sequelize = require('sequelize');
const bodyParser = require('body-parser');
const User = require('../models/User');

const config = require('config');

// const secret = 'dassdfdd';

users.use(
  bodyParser.urlencoded({
    extended: false
  })
);

users.use(bodyParser.json());

users.use(cors());

users.post('/authenticate', (req, res) => {
  User.findOne({
    where: {
      email: req.body.email
    }
  }).then(user => {
    if (user) {
      if (bcrypt.compareSync(req.body.password, user.password)) {
        const payload = {
          id: user.id,
          name: user.first_name
        };
        var token = jwt.sign(payload, config.get('secret'), {
          expiresIn: 1440 // expires in 24 hours
        });

        // res.cookie('auth', token);
        res.cookie('jwt', token, { httpOnly: true, secure: true });
        // return the information including token as JSON
        // // res.setHeader('token', token);
        // res.setHeader('Authorization', 'Bearer ' + token);
        res.send({
          message: 'authentication done ',
          token: token,
          user: user.toJSON()
        });

        console.log(token);
        console.log('Successful Login');
        console.log(user.first_name);
      } else {
        res.json({ message: 'please check your password !' });
        console.log('incorrect password');
      }
    } else {
      res.json({ message: 'user not found !' });
      console.log('user cannot be found');
    }
  });
});

users.get('/protected', (req, res) => {
  res.send('protected');
});


users.get('/getUser', auth, function(req, res) {
  // const currentUser = req.;
  // const id = parseInt(req.params.id);

  const users = User.findOne({
    where: { id: req.user.id }
  });
  //   }
  // });
  // if (!users) {
  //   return res.status(404).send('Cannot find your team players');
  // }
  console;
  res.status(200).json(users);
});


module.exports = users;

Login Component

import React, { Component } from 'react';
import axios from 'axios';
import { withRouter } from 'react-router-dom';

    class Login extends Component {
      constructor() {
        super();
        this.state = {
          email: '',
          password: '',
          errors: {}
        };

        this.onChange = this.onChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
      }

      onChange(e) {
        this.setState({ [e.target.name]: e.target.value });
      }
      onSubmit(e) {
        e.preventDefault();

        // const user = {
        //   email: this.state.email,
        //   password: this.state.password
        // };

        axios
          .post('http://localhost:5000/api/authenticate', {
            email: this.state.email,
            password: this.state.password
          })
          .then(res => {
            localStorage.setItem('token', res.data.token);
            this.props.history.push('/Profile');
          });
      }

auth.js this is my middleware file

const jwt = require('jsonwebtoken');
const config = require('config');

module.exports = function(req, res, next) {
  const token = req.header('Authorization');

  if (!token) {
    return res.status(401).send('Access denied. No JWT provided.');
  }

  try {
    const decoded = jwt.verify(token, config.get('secret'));
    res.set('Authorization', token);
    req.user = decoded;

    next();
  } catch (ex) {
    res.status(400).send('Invalid JWT.');
  }
};

Profile Component( this is the page , i want the users data to appear)

import React, { Component } from 'react';
import { getJwt } from '../helpers/jwt';
import axios from 'axios';
import { withRouter } from 'react-router-dom';

class Profile extends Component {
  constructor(props) {
    super(props);
    this.state = {
      // users: []
    };
  }

  componentDidMount() {
    const jwt = getJwt();
    if (!jwt) {
      this.props.history.push('/Login');
    }


axios
  .get('http://localhost:5000/api/getUser', {
    headers: { Authorization: `Bearer ${jwt}` }
  })
  .then(res => {
    this.profile = res.data;
    console.log('profile is:', res.data);
  })
  .catch(error => console.log(error));

}

2
  • You can use Network tab in chrome's dev tool to view your request. Check if it has header value Commented Jul 21, 2019 at 0:29
  • @TienDuong I can see the token within the request headers , it is stored in the Authorization field Commented Jul 21, 2019 at 14:33

1 Answer 1

2

Inside your auth.js middleware file, you have const token = req.header('Authorization');. This includes the Bearer prefix which is not part of the JWT itself, and will need to be removed before the token can be parsed by the JWT library.

The Bearer prefix identifies the token type as a Bearer token under the OAuth 2.0 Authorization Framework. If you wish to support other token types the prefix will be different to identify the respective type and framework.

Sign up to request clarification or add additional context in comments.

4 Comments

When I removed const token , I now receive token is not defined which is correct however I am unclear what i am meant to define token as. I gave that website a read which you linked. hopefully you can help me furhter. thanks for the reply
Cheers got it working , let token = req.headers['x-access-token'] || req.headers['authorization']; // Express headers are auto converted to lowercase if (token.startsWith('Bearer ')) { // Remove Bearer from string token = token.slice(7, token.length); } const options = { expiresIn: '2d' };
just for future reference to those with same problem
Glad to help. Your original method req.header('Authorization') actually works as too since the req.header() method, which is an alias for req.get(), is case-insensitive, see expressjs.com/en/api.html#req.get. for Express 4.x. Important part was to remove the "Bearer" portion from the front part of the string value which was returned from the method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.