我正在遵循一个关于全栈登录/auth应用程序的指南。它最初是用类组件编写的,我正在用功能组件/钩子重新创建它。我可以通过Postman成功发布请求,但不能通过React/redux。我知道这可能是一个cors问题,但我已经尝试过实现cors,但它根本不起作用。我也尝试过在我的一些axios帖子中添加标题,但也没有成功。以下是现在的一些情况
authActions.js->我的功能发布请求注册用户
...
axios.defaults.headers.post['Accept'] = 'application/json';
axios.defaults.headers.post['Content-Type'] = 'application/json';
//register user
export const registerUser = (userData, history) => (dispatch) => {
axios.post('/api/users/register', userData).then(res => history.push('/login')).catch((err)=>{
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
});
};
...
server.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
require('dotenv').config();
const passport = require('passport');
const cors = require('cors');
const users = require('./routes/api/users');
const app = express();
app.use(cors());
//body-parser middleware
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
//connect to db
const URI = process.env.URI;
mongoose.connect(URI, {useNewUrlParser: true}).then(()=>console.log('MongoDB connected successfully')).catch(err => console.log(err));
//Passport middleware
app.use(passport.initialize());
//Passport config
require("./config/passport")(passport);
//Routes
app.use('/api/users', users);
//Print to server that its listening at given port
const port = process.env.PORT;
app.listen(port, ()=> console.log(`Server listening on port ${port}`));
users.js我试着在这个帖子请求中添加了不同选项的cors。还尝试了router.use(cors(((,但没有成功。
...
router.post('/register', (req, res)=>{
const {errors, isValid} = validateRegisterInput(req.body);
//check validation
if(!isValid){
return res.status(400).json(errors);
}
User.findOne({email: req.body.email}).then(user => {
if(user){
return res.status(400).json({email: "Email already exists"});
} else {
const newUser = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password
});
//hash password before saving to database
bcrypt.genSalt(10, (err, salt)=>{
bcrypt.hash(newUser.password, salt, (err, hash)=>{
if(err) throw err;
newUser.password = hash;
newUser.save().then(user=>res.json(user)).catch(err=>console.log(err));
});
});
}
});
});
...
passport.js
const jwtStrategy = require('passport-jwt').Strategy;
const extractJwt = require('passport-jwt').ExtractJwt;
const mongoose = require('mongoose');
const user = mongoose.model('User');
require('dotenv').config();
const options = {};
options.jwtFromRequest = extractJwt.fromAuthHeaderAsBearerToken();
options.secretOrKey = process.env.secretKey;
module.exports = passport => {
passport.use(
new jwtStrategy(options, (jwt_payload, done)=>{
user.findById(jwt_payload.id).then(user=>{
if(user){
return done(null, user);
}
return done(null, false);
}).catch(err => console.log(err));
})
)
};
谢谢!
我认为这可能是我编写这些功能组件的方式,我仍在学习如何做到这一点。我想这可能与我的道具和我的商店有关
function withRouter(Component){
function ComponentWithRouterProp(props){
let location = useLocation();
let navigate = useNavigate();
let params = useParams();
return(
<Component
{...props} router={{location, navigate, params}}
/>
);
}
return ComponentWithRouterProp;
}
const Register = (props) =>{
const [state, setState] = useState({
name: "",
email: "",
password: "",
password2: "",
errors: {}
});
useEffect(()=>{
if(props.errors){
setState({
errors: props.errors
})
}
}, [props])
useEffect(()=>{
if(props.auth.isAuthenticated){
props.history.push('/dashboard');
}
}, [props]);
const onChange = (e) =>{
setState({
...state,
[e.target.name]: e.target.value
});
}
const submit = (e) =>{
e.preventDefault();
const newUser = {
name: state.name,
email: state.email,
password: state.password,
password2: state.password2
};
props.registerUser(newUser, props.history)
console.log(newUser);
};
return(
<div className='container'>
<div className='row'>
<div className='col s8 offset-s2'>
<Link to="/" className='btn-flat waves-effect'>
<i className='material-icons left'>keyboard_backspace</i>Back to home
</Link>
<div className='col s12'>
<h4>
<b>Register</b> below
</h4>
<p className='grey-text text-darken-1'>
Already have an account? <Link to="/login">Log in</Link>
</p>
</div>
<form noValidate onSubmit={submit}>
<div className='input-field col s12'>
<input name="name" className={classnames("", {invalid: props.errors.name})} onChange={onChange} defaultValue={state.name} error={state.errors.name} id="name" type="text" />
<label htmlFor='name'>Name</label>
<span className="red-text">{props.errors.name}</span>
</div>
<div className='input-field col s12'>
<input name="email" className={classnames("", {invalid: props.errors.email})} onChange={onChange} defaultValue={state.email} error={state.errors.email} id="email" type="text" />
<label htmlFor='email'>Email</label>
<span className="red-text">{props.errors.email}</span>
</div>
<div className='input-field col s12'>
<input name="password" className={classnames("", {invalid: props.errors.password})} onChange={onChange} defaultValue={state.password} error={state.errors.password} id="password" type="password" />
<label htmlFor='password'>Password</label>
<span className="red-text">{props.errors.password}</span>
</div>
<div className='input-field col s12'>
<input name="password2" className={classnames("", {invalid: props.errors.password2})} onChange={onChange} defaultValue={state.password2} error={state.errors.password2} id="password2" type="password" />
<label htmlFor='password2'>Confirm Password</label>
<span className="red-text">{props.errors.password2}</span>
</div>
<div className='col s12'>
<button type='submit' className='btn btn-large waves-effect waves-light hoverable blue accent-3'>Sign up</button>
</div>
</form>
</div>
</div>
</div>
)
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ registerUser })(withRouter(Register));
我收到一个403 Forbidden错误,因为我的代理设置不正确。我最初在客户端的package.json代理中为端口5000设置了它,但当我在5000上运行服务器时,它告诉我已经有5000在使用。我在我的.env文件中更改了它,但在我的客户端package.json的代理设置中没有更改