Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React axios 401 unauthorized

I get a 401 error, when trying to authenticate a user. Just to give context, React is using an Express server, and using Passport for authentication. React has a port of 8001, and the Express server has the port of 8000.

GET /api/users/user 401 2.167 ms - 59

enter image description here

enter image description here

Other get requests Do work. For example

enter image description here

React

export const getUser = () => {

    return async (dispatch) =>{
        Axios.get('/api/users/user')
        .then( (res) => {
            console.log(res.data);
            localStorage.setItem('auth', res.data.authenticated);
            dispatch({type: GET_USER, res});
        }).catch( (err) => {
            console.log(err);
        })
    }
}

axios

import Axios from 'axios'

let AxiosInstance = Axios.create({
  baseURL: process.env.REACT_APP_BASE_URL, // http://localhost:8000
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
  },

})

// AxiosInstance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'

AxiosInstance.interceptors.response.use(function(response) {
  return response;
})

export default AxiosInstance

routes/user

router.get('/user', (req, res, next) => {
    if(req.user) {
        return res.status(200).json({
            user: req.user,
            authenticated: true
        });
    } else {
        return res.status(401).json({
            error: 'User is not authenticated',
            authenticated: false
        });
    }
});

File app.js

var express = require('express');
var app = express();
var userRoute = require('./routes/users');
var postRoute  = require('./routes/posts');
var bodyParser = require('body-parser');
var logger = require('morgan');
var models = require('./models');
var User = require('./models/user');
var session = require('express-session');
var cookieParser = require('cookie-parser') ;
var cookieSession = require('cookie-session');
var dotenv = require('dotenv');
var env = dotenv.config();
var cors = require('cors');
const port = process.env.PORT || 8000;
const passport = require('passport');
const path = require('path');
const allowOrigin = process.env.ALLOW_ORIGIN || '*'

// CORS Middleware

if (!process.env.PORT) {
  require('dotenv').config()
}

if (!process.env.PORT) {
  console.log('[api][port] 8000 set as default')
  console.log('[api][header] Access-Control-Allow-Origin: * set as default')
} else {
  console.log('[api][node] Loaded ENV vars from .env file')
  console.log(`[api][port] ${process.env.PORT}`)
  console.log(`[api][header] Access-Control-Allow-Origin: ${process.env.ALLOW_ORIGIN}`)
}


app.use(logger('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false })); 




app.use(cors({
  origin: process.env.ALLOW_ORIGIN,
  credentials: true,
  allowedHeaders: 'X-Requested-With, Content-Type, Authorization',
  methods: 'GET, POST, PATCH, PUT, POST, DELETE, OPTIONS'
}))

app.use(session({
  secret : 'nodeauthsecret',
  resave: false,
 saveUninitialized: true,

}));

app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
require('./config/passport-github')(passport);

app.use(function(req, res, next) {
  res.locals.user = req.user; // This is the important line
  console.log(res.locals.user);
  next();
});
// app.use(function(req, res, next) {
//   res.setHeader("Access-Control-Allow-Origin", "*");
//   res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
// });

app.use('/api/users', userRoute )

app.use('/api/posts',  postRoute )

app.listen(port, () => {
  console.log('[api][listen] http://localhost:' + port)
})

passport.js

const BCRYPT_SALT_ROUNDS = 12;

const passport = require('passport'),

  bcrypt = require('bcrypt'),
  JWTstrategy = require('passport-jwt').Strategy,
  ExtractJWT = require('passport-jwt').ExtractJwt,
  Sequelize = require('sequelize'),
  Op = Sequelize.Op;

module.exports = function(passport, user) {
  const models = require( '../models/index');
  const localStrategy = require('passport-local').Strategy;
// serialize session, only store user id in the session information
  passport.serializeUser(function(user, done) {
    done(null, user.id);
  });

  // from the user id, figure out who the user is...
  passport.deserializeUser(function(userId, done){
    models.User
      .find({ where: { id: userId } })
      .then(function(user){
        done(null, user);
      }).catch(function(err){
        done(err, null);
      });
  });

  passport.use(
    'register',
    new localStrategy(
      {
        usernameField: 'username',
        passwordField: 'password',
        passReqToCallback: true,
        session: false,
      },
      (req, username, password, done) => {
        try {
           models.User.findOne({
            where: {
              [Op.or]: [
                {
                  username: username,
                },
                { email: req.body.email },
              ],
            },
          }).then(user => {
            if (user != null) {
              console.log('username or email already taken');
              return done(null, false, {
                message: 'username or email already taken',
              });
            } else {
              bcrypt.hash(password, BCRYPT_SALT_ROUNDS).then(hashedPassword => {
                models.User.create({
                  username: req.body.username,
                  password: hashedPassword,
                  email: req.body.email
                }).then(user => {
                  console.log('user created');
                  return done(null, user);
                });
              });
            }
          });
        } catch (err) {
          done(err);
        }
      },
    ),
  );



passport.use(
  'login',
  new localStrategy(
    {
      usernameField: 'username',
      passwordField: 'password',
      session: false
    },
    (username, password, done, req) => {
      try {
        models.User.findOne({
          where: {
            [Op.or]: [
              {
                username: username,
              }
            ],
          },
        }).then(user => {
          if (user === null) {
            return done(null, false, { message: 'Username doesn\'t exist' });

          } else {
            bcrypt.compare(password, user.password).then(response => {
              if (response !== true) {
                console.log('passwords do not match');
                return done(null, false, { message: 'passwords do not match' });
              }

              console.log('user found & authenticated');
              // note the return needed with passport local - remove this return for passport JWT
              return done(null, user);
            });


          }
        });
      } catch (err) {
        done(err);
      }
    },
  ),
);

const opts = {
  jwtFromRequest: ExtractJWT.fromAuthHeaderWithScheme('JWT'),
  secretOrKey: process.env.jwtsecret,
};




passport.use(
  'jwt',
  new JWTstrategy(opts, (jwt_payload, done) => {
    try {
       models.User.findOne({
        where: {
          username: jwt_payload._id,
        },
      }).then(user => {
        if (user) {
          console.log('user found in db in passport');
          // note the return removed with passport JWT - add this return for passport local
          done(null, user);
          // console.log(user);
        } else {
          console.log('user not found in db');
          done(null, false);
        }
      });
    } catch (err) {
      done(err);
    }
  }),
);


}
like image 503
randal Avatar asked Feb 17 '19 05:02

randal


1 Answers

You are facing this because your req.user is empty that's why it goes to else statement and returns Unauthorized which you are returning.

Check your server console if it is printing anything console.log(res.locals.user);

Send your auth token with headers like this

headers : {
  'Content-Type' : 'application/json',
  'Accept' : 'application/json',
  'Authorization' : 'Bearer <token_here>'
}

Updated

Your request will always return 401 unauthorized.

https://github.com/manjurulhoque/nodejs-ecommerce-api/blob/master/routes/users.js#L105

Check my code. To get logged in user you have to use

passport.authenticate('jwt', { session: false })
like image 74
Manzurul Hoque Rumi Avatar answered Nov 19 '22 20:11

Manzurul Hoque Rumi