web-dev-qa-db-ja.com

React axios 401無許可

ユーザーを認証しようとすると、401エラーが発生します。コンテキストを説明するだけのために、ReactはExpressサーバーを使用しており、認証にPassportを使用しています。Reactは8001、およびExpressサーバーのポートは8000

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

enter image description here

enter image description here

その他のgetリクエストは機能します。例えば

enter image description here

反応

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
        });
    }
});

ファイル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);
    }
  }),
);


}
3
randal

あなたの_req.user_が空であるのでこれに直面しています。それがelseステートメントに行き、返っているUnauthorizedを返す理由です。

何かを印刷していないかサーバーコンソールを確認してくださいconsole.log(res.locals.user);

このようなヘッダーを持つ_auth token_を送信します

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

更新

リクエストは常に_401 unauthorized_を返します。

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

コードを確認してください。ログインしたユーザーを取得するには、使用する必要があります

_passport.authenticate('jwt', { session: false })
_
2

[〜#〜] mdn [〜#〜] で述べたように、ヘッダーにAuthorizationを設定する必要があると思います

HTTP Authorizationリクエストヘッダーには、サーバーでユーザーエージェントを認証するための認証情報が含まれています。通常、サーバーが401 Unauthorized statusおよびWWW-Authenticateヘッダー。

let ExtractJwt = passportJWT.ExtractJwt;  
let Strategy = passportJWT.Strategy;  
let opts = {}
opts.secretOrKey= cfg.jwtSecret
opts.jwtFromRequest= ExtractJwt.fromAuthHeaderWithScheme(cfg.authScheme)

new JWTstrategy(
...
return {
        initialize: function() {
            return passport.initialize();
        },
        authenticate: function() {
            return passport.authenticate(cfg.authScheme, cfg.jwtSession);
        }
    };
)
0
Ahm.