将Axios的Auth POST请求定向到错误的http地址并返回404



我的应用程序的身份验证有问题。当从客户端向发送POST请求(其中包含注册组件中表单的信息(时,我在控制台中收到以下错误:

POST http://localhost:3000/api/auth/signup 404 (Not Found)

我知道将POST请求定向到的正确地址是"localhost:5005",这是我的服务器运行的地方。但是,当我不在客户端的"services/auth.js"中硬编码时,它默认为"localhost:3000"并抛出错误。但我不能在定义的地方/需要改变的地方锻炼。

如果我将POST请求的目标硬编码为http://localhost:5005/api/auth/signup',则代码将运行,并在数据库中创建新的用户条目。

仅供参考下面的代码抛出404错误,如上所述。

提前感谢!如果我遗漏了任何重要信息,请告诉我。

client/src/services/auth.js

```
import axios from 'axios';
const signup = (email, password, firstname, lastname) => {
return axios
.post('/api/auth/signup', { email, password, firstname, lastname})
.then(response => {
// console.log(response)
return response.data;
})
.catch(err => {
// console.log(err)
return err.response.data;
});
};
const login = (email, password) => {
return axios
.post('/api/auth/login', { email, password })
.then(response => {
return response.data;
})
.catch(err => {
return err.response.data;
});
};
const logout = () => {
return axios
.delete('/api/auth/logout')
.then(response => {
return response.data;
})
.catch(err => {
return err.response.data;
});
};
export { signup, login, logout };
```

client/src/components/Signup.js

```
import { React, useState } from 'react'
import { signup } from '../services/auth'
function useInput(initialValue){
const [value, setValue] = useState(initialValue);

function handleChange(event){
setValue(event.target.value);
}
return [value,handleChange]
}
export default function Signup(props) {
const [email, setEmail] = useInput('');
const [password, setPassword] = useInput('');
const [firstname, setFirstname] = useInput('');
const [lastname, setLastname] = useInput('');
const [message, setMessage] = useState('');
const [user, setUser] = useState('')
const handleSubmit = event => {
event.preventDefault();
console.log('email:', email, 'password:', password, 'firstname:', firstname, 'lastname:', lastname)
signup(email, password, firstname, lastname).then(data => {
if (data.message) {
// console.log(data.message);
setMessage(data.message);
// setEmail('');
// setPassword('');
// setFirstname('');
// setLastname('')
} else {
setUser(data)
console.log(user)
props.history.push('/dashboard');
}
});
};
return (
<div>
<h1>User signup</h1>
<div class='signupForm'>
<form onSubmit={handleSubmit}>
<label>Email</label>
<input 
type='text'
name='email'
value={email}
onChange={setEmail}
id='email'
/>
<label>Password</label>
<input 
type='password'
name='password'
value={password}
onChange={setPassword}
id='password'
/>
<label>Firstname</label>
<input 
type='text'
name='firstname'
value={firstname}
onChange={setFirstname}
id='firstname'
/>
<label>Lastname</label>
<input 
type='text'
name='lastname'
value={lastname}
onChange={setLastname}
id='lastname'
/>

{message && (
<alert variant='danger'>{message}</alert>
)}
<button type='submit'>Signup</button>
</form>
</div>
</div>
)
}
```

(服务器(路由/auth-routes.js

```
const express = require('express');
const passport = require('passport');
const bcrypt = require('bcrypt');
const User = require('../models/User.model');
const router = express.Router();
// Signup route
router.post('/signup', (req, res) => {
const {
email, password, firstname, lastname,
} = req.body;
if (!password || password.length < 8) {
return res
.status(400)
.json({ message: 'Your password must be 8 char. min.' });
}
if (!email) {
return res.status(400).json({ message: 'Your email cannot be empty' });
}
// check if username exists in database -> show message
User.findOne({ email })
.then((found) => {
if (found) {
return res
.status(400)
.json({ message: 'This email is already taken' });
}
// hash the password, create the user and send the user to the client
const salt = bcrypt.genSaltSync();
const hash = bcrypt.hashSync(password, salt);
return User.create({
email, password: hash, firstname, lastname,
}).then(
(dbUser) => {
// login with passport:
req.login(dbUser, (err) => {
if (err) {
return res
.status(500)
.json({ message: 'Error while attempting to login' });
}
return res.status(200).json(dbUser);
});
},
);
})
.catch((err) => {
res.json(err);
});
});
// Login route
router.post('/login', (req, res) => {
passport.authenticate('local', (err, user) => {
if (err) {
return res.status(500).json({ message: 'Error while authenticating' });
}
if (!user) {
return res.status(400).json({ message: 'Wrong credentials' });
}
req.login(user, (error) => {
if (error) {
return res
.status(500)
.json({ message: 'Error while attempting to login' });
}
return res.json(user);
});
})(req, res);
});
// Delete user route
router.delete('/logout', (req, res) => {
req.logout();
res.json({ message: 'Successful logout' });
});
// returns the logged in user
router.get('/loggedin', (req, res) => {
res.json(req.user);
});
// when login is successful, retrieve user info
router.get('/login/success', (req, res) => {
if (req.user) {
res.json({
success: true,
message: 'user has successfully authenticated',
user: req.user,
cookies: req.cookies,
});
}
});
// auth with google
router.get(
'/google',
passport.authenticate('google', {
scope: [
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email',
],
}),
);
router.get(
'/google/callback',
passport.authenticate('google', {
successRedirect: '/private-page',
// eslint-disable-next-line max-len
failureRedirect: '/login', // here you would redirect to the login page using traditional login approach
}),
);
module.exports = router;
```

app.js

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const bcrypt = require('bcrypt');
const cors = require('cors');
// ℹ️ Gets access to environment variables/settings
// https://www.npmjs.com/package/dotenv
require('dotenv/config');
// ℹ️ Connects to the database
require('./db');
// Handles http requests (express is node js framework)
// https://www.npmjs.com/package/express
const express = require('express');
const app = express();
// ℹ️ This function is getting exported from the config folder. It runs most middlewares
require('./config')(app);
app.use(
cors({
// this could be multiple domains/origins, but we will allow just our React app
origin: ['http://localhost:3000'],
}),
);
// session configuration
const session = require('express-session');
// session store using mongo
const MongoStore = require('connect-mongo')(session);
const mongoose = require('./db/index');
app.use(
session({
secret: process.env.SESSION_SECRET,
cookie: { maxAge: 1000 * 60 * 60 * 24 },
saveUninitialized: false,
// Forces the session to be saved back to the session store,
// even if the session was never modified during the request.
resave: true,
store: new MongoStore({
// mongooseConnection: mongoose.connection,
url: 'mongodb://localhost:27017',
}),
}),
);
// end of session configuration
// passport configuration
const User = require('./models/User.model');
// we serialize only the `_id` field of the user to keep the information stored minimum
passport.serializeUser((user, done) => {
// eslint-disable-next-line no-underscore-dangle
done(null, user._id);
});
// when we need the information for the user, the deserializeUser function is called with
// the id that we previously serialized to fetch the user from the database
passport.deserializeUser((id, done) => {
User.findById(id)
.then((dbUser) => {
done(null, dbUser);
})
.catch((err) => {
done(err);
});
});
passport.use(
new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENTID,
clientSecret: process.env.GOOGLE_CLIENTSECRET,
callbackURL: '/auth/google/callback',
},
(accessToken, refreshToken, profile, done) => {
// to see the structure of the data in received response:
console.log('Google account details:', profile);
User.findOne({ googleID: profile.id })
.then((user) => {
if (user) {
done(null, user);
return;
}
User.create({ googleID: profile.id })
.then((newUser) => {
done(null, newUser);
})
.catch((err) => done(err)); // closes User.create()
})
.catch((err) => done(err)); // closes User.findOne()
},
),
new LocalStrategy((username, password, done) => {
// login
User.findOne({ username })
.then((userFromDB) => {
if (userFromDB === null) {
// there is no user with this username
done(null, false, { message: 'Wrong Credentials' });
} else if (!bcrypt.compareSync(password, userFromDB.password)) {
// the password is not matching
done(null, false, { message: 'Wrong Credentials' });
} else {
// the userFromDB should now be logged in
done(null, userFromDB);
}
})
.catch((err) => {
console.log(err);
});
}),
);
app.use(passport.initialize());
app.use(passport.session());
// end of passport
// 👇 Start handling routes here
// Contrary to the views version, all routes are controled from the routes/index.js
const index = require('./routes');
app.use('/api', index);
const auth = require('./routes/auth-routes');
app.use('/api/auth', auth);
// Allows access to the API from different domains/origins BEFORE session
app.use(
cors({
// this could be multiple domains/origins, but we will allow just our React app
origin: ['http://localhost:3000'],
}),
);
// 👇 Start handling routes here
// Contrary to the views version, all routes are controled from the routes/index.js
// This could be a conflict with line 104, so I commented it out. We can reinstate
// const allRoutes = require('./routes');
// app.use('/api', allRoutes);
const admin = require('./routes/admin');
app.use('/api', admin);
// ❗ To handle errors. Routes that don't exist or errors that you handle in specific routes
require('./error-handling')(app);
module.exports = app;

但我无法在定义的地方/需要更改的地方锻炼。

这是前端运行的地方,您使用的是相对url。你可能只是想做:

axios.defaults.baseURL = 'http://localhost:5005';

当您编写时

return axios
.post('/api/auth/signup'

这意味着您有一个端点和您的前端在同一台服务器上运行,即本地主机:3000,但在您的情况下,您在前端服务器上没有端点。

最新更新