• 1000 * Странная вещь, которая происходит, я получаю:
Из вкладки сети:
http://localhost:8016/users/login 401 (Unauthorized)
& От клиента:
TypeError: Cannot read property '0' of undefined
Что странного Uncaught TypeError
, он исходит:
Внутри некоторого logi c, который должен запускаться только из ответа от сервера, если вы зарегистрировали и существуют в базе данных, но не проверены. Прямо сейчас я очистил базу данных пользователей и переход к ней?
Несмотря на то, что на этом маршруте были только эти ответы:
router.post('/login', passport.authenticate('local'), function(req, res) {
var user = req.user;
if (user === undefined) {
return res.status(401).send({
msg: [
`We were unable to find this user.`,
`This email and/or password combo may be incorrect.
Please confirm with the "Forgot password" link above or the "Register" link below!`
]
});
}
if (user && user.isVerified === false) {
return res.status(401).send({
msg: [
'Your username has not been verified!',
'Check your email for a confirmation link.'
]
});
} else {
return res.status(200).send({
msg: [`Your have successfully logged in;`, `Welcome to Hillfinders!`]
});
}
});
Что еще, когда я смотрю на вкладку сети, чтобы увидеть каков ответ, чтобы получить более точный ответ, я просто получаю:
Мои ответы соответствуют формату, в котором я отправляю код состояния для своего клиента и сообщение, которое я также использую для пользовательского интерфейса клиента:
Выдержка из логина:
if (user && user.isVerified === false) {return res.status (401) .send ({msg: ['Ваше имя пользователя не подтверждено!', 'Проверьте свою электронную почту на наличие ссылки для подтверждения.']}); } else {
Это мой компонент формы:
Я пропустил другие части формы, поскольку они не имеют значения для вопроса:
import { useState, useEffect } from 'react';
import {
Loader,
Input,
Dimmer,
Transition,
Button,
Form,
Grid,
Header,
Message,
Segment
} from 'semantic-ui-react';
import axios from 'axios';
import {
logInUser,
userHasBeenVerified,
userHasNotBeenVerified,
resetUserAcoountVerified
} from '../../store/reducers/users/index';
import { Link } from 'react-router-dom';
import { validateInputs } from '../../utils/index';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { Container } from 'next/app';
import dynamic from 'next/dynamic';
const MyMap = dynamic(() => import('../Map/MyMap.jsx'), {
ssr: false
});
function FormComponent({
formType,
match,
history,
logInUser,
accountNotVerified,
userHasBeenVerified,
userHasNotBeenVerified,
resetUserAcoountVerified
}) {
var Forms = {
Hillfinders: [isHillfindersForm],
Confirmation: [isConfirmationForm],
ForgotPassword: [isForgotPasswordForm, forgotPasswordSubmit],
Login: [isLoginForm, loginSubmit],
Registration: [isRegisterForm, registerSubmit],
UpdatePassword: [isUpdatePasswordForm, updatePasswordSubmit]
};
var [duration, setDuration] = useState(500);
var [username, setUsername] = useState('');
var [usernameFeedback, setUsernameFeedback] = useState('');
var [usernameError, setUsernameError] = useState(false);
var [userNameDup, setUserNameDup] = useState(false);
var [password, setPassword] = useState('');
var [passwordFeedback, setPasswordFeedback] = useState('');
var [passwordError, setPasswordError] = useState(false);
var [password_confirmation, setPasswordConfirmation] = useState('');
var [passwordConfirmationError, setPasswordConfirmationError] = useState(false);
var [passwordConfirmationFeedback, setPasswordConfirmationFeedback] = useState('');
var [formSuccess, setFormSuccess] = useState(false);
var [formError, setFormError] = useState(false);
var [disableButton, setDisableButton] = useState(false);
var [isLoading, setIsLoading] = useState(false);
var [responseMessage, setResponseMessage] = useState(['', '']);
var [tokenExpired, setTokenExpired] = useState(false);
var [responseCodeSuccess, setResponseCodeSuccess] = useState(false);
var [error, setError] = useState(false);
function isLoginForm() {
console.log('accountNotVerified ', accountNotVerified);
useEffect(() => {}, []);
return (
<div className="login-form">
{' '}
{}
<style>
{`body > div, body > div > div, body > div > div > div.login-form { height: 100%;}`}{' '}
</style>
<Grid textAlign="center" style={{ height: '100%' }} verticalAlign="middle">
<Grid.Column style={{ maxWidth: 450 }}>
<Header as="h2" color="green" textAlign="center">
Log-in to your account
</Header>
<Form
size="large"
onSubmit={e => handleSubmit(e, formType)}
error={formError}
>
<Segment stacked>
<Form.Input
fluid
icon="user"
iconPosition="left"
placeholder="E-mail address, e.g. joe@schmoe.com"
name="username"
value={username}
onChange={handleChange}
/>
<Transition visible={usernameError} animation="scale" duration={duration}>
<Message error content={usernameFeedback} />
</Transition>
<Form.Input
fluid
icon="lock"
iconPosition="left"
placeholder="Password"
name="password"
type="password"
value={password}
onChange={e => handleChange(e)}
/>
<Transition visible={passwordError} animation="scale" duration={duration}>
<Message error content={passwordFeedback} />
</Transition>
<Button color="green" fluid size="large" disabled={disableButton}>
Log-in
</Button>
<br />
<Link to="/forgot_password">Forgot password?</Link>
<Transition
visible={accountNotVerified}
unmountOnHide={true}
animation="scale"
duration={duration}
>
{isLoading ? (
<Dimmer active inverted>
<Loader />
</Dimmer>
) : (
<Message
warning
color="yellow"
centered="true"
header={responseMessage[0]}
content={responseMessage[1]}
/>
)}
</Transition>
<Transition
visible={formError}
unmountOnHide={true}
animation="scale"
duration={duration}
>
{isLoading ? (
<Dimmer active inverted>
<Loader />
</Dimmer>
) : (
<Message
error
centered="true"
header={responseMessage[0]}
content={responseMessage[1]}
/>
)}
</Transition>
<Transition
visible={formSuccess}
unmountOnHide={true}
animation="scale"
duration={duration}
>
{isLoading ? (
<Dimmer active inverted>
<Loader />
</Dimmer>
) : (
<Message
success
header={responseMessage[0]}
content={responseMessage[1]}
/>
)}
</Transition>
</Segment>
</Form>
{formError ? (
<Transition visible={formError} animation="scale" duration={1000}>
{isLoading ? (
<Dimmer active inverted>
<Loader />
</Dimmer>
) : (
<Message>
<Link to="/register">Register</Link>{' '}
</Message>
)}
</Transition>
) : null}
</Grid.Column>{' '}
</Grid>{' '}
</div>
);
}
function loginSubmit() {
axios
.post('/users/login', {
username: username,
password: password
})
.then(response => {
console.log('response', response);
if (response.status === 200) {
setTimeout(() => {
logInUser();
history.push('/profile');
}, 5000);
setUsername('');
setPassword('');
setFormError(false);
setFormSuccess(true);
setIsLoading(false);
setResponseMessage(response.data.msg);
userHasBeenVerified();
}
})
.catch(function(error) {
if (error.response) {
if (error.response.status === 401) {
setUsername('');
setPassword('');
setFormError(false);
setFormSuccess(false);
setIsLoading(false);
setResponseMessage(error.response.data.msg);
}
if (error.response.status === 404) {
setUsername('');
setPassword('');
setFormError(true);
setFormSuccess(false);
setIsLoading(false);
setResponseMessage(error.response.data.msg);
}
}
});
}
function handleChange(e) {
e.persist();
setFormError(false);
setFormSuccess(false);
setUsernameError(false);
setPasswordError(false);
setDisableButton(false);
resetUserAcoountVerified();
setUserNameDup(false);
if (e.target.name === 'username') {
setUsername(e.target.value);
}
if (e.target.name === 'password') {
setPassword(e.target.value);
}
if (e.target.name === 'password_confirmation') {
setPasswordConfirmation(e.target.value);
}
}
function handleSubmit(event, formType) {
event.preventDefault();
console.log('before validate');
validateInputs(
formType,
username,
setUsernameError,
setUsernameFeedback,
password,
password_confirmation,
setPasswordConfirmationError,
setPasswordConfirmationFeedback,
setPasswordError,
setPasswordFeedback,
setDisableButton,
setFormSuccess,
setFormError
);
console.log('after validate');
return Forms[formType][1]();
}
return Forms[formType][0]();
}
function mapStateToProps(state) {
const { users } = state;
const { accountNotVerified, isLoggedIn } = users;
return { accountNotVerified, isLoggedIn };
}
const mapDispatchToProps = dispatch =>
bindActionCreators(
{ logInUser, userHasBeenVerified, userHasNotBeenVerified, resetUserAcoountVerified },
dispatch
);
export default connect(
mapStateToProps,
mapDispatchToProps
)(FormComponent);
Любая помощь были бы признательны!
ОБНОВЛЕНИЕ: Ajeet ниже сделал хорошее замечание, поэтому я также включаю часть auth из паспорта-local:
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var UserModel = require('../models/userModel');
passport.use(
new LocalStrategy(
{ usernameField: 'username', passwordField: 'password' },
async (username, password, done) => {
try {
const user = await UserModel.findOne({ username: username }).exec();
if (!user) {
return done(null, false, { message: 'Invalid username!' });
}
const passwordOk = await user.comparePassword(password);
if (!passwordOk) {
return done(null, false, {
message: 'Invalid password!'
});
}
return done(null, user);
} catch (err) {
return done(err);
}
}
)
);
// eslint-disable-next-line no-underscore-dangle
passport.serializeUser((user, done) => done(null, user._id));
passport.deserializeUser(async (id, done) => {
try {
const user = await UserModel.findById(id).exec(); //exec is used to get a real Promise
return done(null, user);
} catch (err) {
return done(err);
}
});
module.exports = {
initialize: passport.initialize(),
session: passport.session(),
setUser: (req, res, next) => {
res.locals.user = req.user;
return next();
}
};
Я подумал, когда вы попадете на этот маршрут, хотя passport-local
срабатывает стратегия, помогая с моими функциями маршрутов ...