![](/img/trans.png)
[英]In REACT, GET http:/xxxx 401 (Unauthorized)/ (CORS) : For "localhost"
[英]React profile page, how to avoid 'GET http://localhost:3001/users/profile 401 (Unauthorized)' when trying to get JSON data from back end
对于这个应用程序,我使用的是 React & Express。 我在端口 3000 上运行 React,在端口 3001 上运行 Express。在 Express 端,我有使用 JWT 的身份验证工作。
首先,这是我的 auth.js 服务文件:
const jwt = require('jsonwebtoken');
const models = require('../models');
const bcrypt = require('bcryptjs');
var authService = {
signUser: function (user) {
const token = jwt.sign({
Username: user.Username,
UserId: user.UserId
},
'secretkey',
{
expiresIn: '1h'
}
);
return token;
},
verifyUser: function (token) {
try {
let decoded = jwt.verify(token, 'secretkey');
return models.users.findByPk(decoded.UserId);
} catch (err) {
console.log(err);
return null;
}
},
hashPassword: function (plainTextPassword) {
let salt = bcrypt.genSaltSync(10);
let hash = bcrypt.hashSync(plainTextPassword, salt);
return hash;
},
comparePasswords: function (plainTextPassword, hashedPassword) {
return bcrypt.compareSync(plainTextPassword, hashedPassword);
}
}
module.exports = authService;
当用户向注册路由发出 POST 请求时,它会起作用:
router.post('/signup', function (req, res, next) {
models.users.findOrCreate({
where: {
Username: req.body.username
},
defaults: {
FirstName: req.body.firstName,
LastName: req.body.lastName,
Email: req.body.email,
Password: authService.hashPassword(req.body.password)
}
})
.spread(function (result, created) {
if (created) {
res.redirect("http://localhost:3000/login");
} else {
res.send('This user already exist')
}
});
});
注册适用于 Postman 和 React。
当用户向登录路由发出 POST 请求时,它会起作用:
router.post('/login', function (req, res, next) {
models.users.findOne({
where: {
Username: req.body.username
}
}).then(user => {
if (!user) {
console.log('User not found')
return res.status(401).json({
message: "Login Failed"
});
} else {
let passwordMatch = authService.comparePasswords(req.body.password, user.Password);
if (passwordMatch) {
let token = authService.signUser(user);
res.cookie('jwt', token);
res.redirect('http://localhost:3001/users/profile');
} else {
console.log('Wrong Password');
}
}
});
});
登录适用于 Postman 和 React。
当用户向配置文件路由发出 GET 请求时,它会半工作:
router.get('/profile', function (req, res, next) {
let token = req.cookies.jwt;
if (token) {
authService.verifyUser(token).then(user => {
if (user) {
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(user));
} else {
res.status(401);
res.send('Invalid authentication token');
}
});
} else {
res.status(401);
res.send('Invalid authentication token');
}
});
这仅适用于 Postman,我可以使用 Postman 看到我想要的数据。在 React 中,它不会获取我请求的配置文件路由。 这是错误的来源:控制台错误
在 React 端,这是配置文件 GET 组件:
import React from 'react';
import axios from 'axios';
class UserProfile extends React.Component {
constructor(props) {
super(props);
this.state = {
profileData: []
}
};
fetchProfileData = () => {
var encodedURI = window.encodeURI(this.props.uri);
return axios.get(encodedURI).then(response => {
this.setState(() => {
return {
profileData: response.data
};
});
});
};
componentDidMount() {
this.fetchProfileData();
}
render() {
console.log(this.state.profileData);
if (this.state.profileData.length === 0) {
return <div>Failed to fetch data from server</div>
}
const profile = this.state.profileData.map(user => (
<div key={user.UserId}>Hello world</div>
));
return <div>{profile}</div>
}
}
export default UserProfile;
然后当我 go 渲染这个组件时,我只是:
<UserProfile uri="http://localhost:3001/users/profile" />
然后将呈现“无法从服务器获取数据”,然后控制台将记录“401(未经授权)”错误。 我只是无法让它在 React 中呈现。
如果有人想要我的 Express app.js 文件以获取一些额外信息:
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var models = require('./models');
var cors = require('cors');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'hbs');
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(cors());
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
models.sequelize.sync().then(function () {
console.log("DB Synced Up");
});
module.exports = app;
提前谢谢你。 我一直在努力弄清楚这一点。
我试过玩弄我的 UserProfile 组件。 我试过在 Express 中玩弄我的 /profile 路线。 我得到的唯一 2 个错误是 401(未授权)和一些关于标题的错误。 我知道我的 JWT 密钥被传递到反应端,因为当我执行“localhost:3000/profile”(反应端)时,我可以看到我存储了 cookie。 我不确定如何在 React 端获得授权。 在这一点上,我不知道该怎么做。 这是我第一次尝试使用 React 设置身份验证。 我一直使用 Express 和 the.hbs 文件来呈现我的个人资料页面。 但有人告诉我你不应该在后端呈现个人资料页面。 所以,我在这里尝试用 React 来做。
我已经从后端到前端渲染了东西,但是没有使用JWT。我坚信它与JWT cookie有关。 我只是不知道如何在 React 中验证它。 再次感谢。
我通过将其添加到我的 React 项目中来修复它:
{ withCredentials: true }
fetchProfileData = () => {
var encodedURI = window.encodeURI(this.props.uri);
return axios.get(encodedURI, { withCredentials: true }).then(response => {
this.setState(() => {
return {
profileData: response.data
};
});
});
};
然后在 Express 中,我玩弄了我的 Profile 路线。 将数据放入数组中,并按原样发送:
router.get('/profile', function (req, res, next) {
var userData = [];
let token = req.cookies.jwt;
if (token) {
authService.verifyUser(token).then(user => {
userData.push(user);
res.send(userData);
});
} else {
res.status(401);
res.send('Invalid authentication token');
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.