Поэтому я пытаюсь реализовать логику входа в систему с узлом и реагировать, используя монго в качестве базы данных.Сигин в порядке, я подписываю пользователя, и он сохраняется в БД с токеном в браузере.Затем меня перенаправляют на страницу входа в систему, и он говорит, что у меня нет авторизации, даже если у меня сохранен токен.
const mongoose = require('mongoose');
const passport = require('passport');
const router = require('express').Router();
const auth = require('../auth');
const Users = mongoose.model('Users');
//POST new user route (optional, everyone has access)
router.post('/', auth.optional, (req, res, next) => {
const {
body: {
user
}
} = req;
if (!user.email) {
return res.status(422).json({
errors: {
email: 'is required',
},
});
}
if (!user.password) {
return res.status(422).json({
errors: {
password: 'is required',
},
});
}
const finalUser = new Users(user);
finalUser.setPassword(user.password);
return finalUser.save()
.then(() => res.json({
user: finalUser.toAuthJSON()
}));
});
//POST login route (optional, everyone has access)
router.post('/login', auth.optional, (req, res, next) => {
const {
body: {
user
}
} = req;
if (!user.email) {
return res.status(422).json({
errors: {
email: 'is required',
},
});
}
if (!user.password) {
return res.status(422).json({
errors: {
password: 'is required',
},
});
}
return passport.authenticate('local', {
session: false
}, (err, passportUser, info) => {
if (err) {
return next(err);
}
if (passportUser) {
const user = passportUser;
user.token = passportUser.generateJWT();
return res.json({
user: user.toAuthJSON()
});
}
return status(400).info;
})(req, res, next);
});
//GET current route (required, only authenticated users have access)
router.get('/current', auth.required, (req, res, next) => {
const {
payload: {
id
}
} = req;
return Users.findById(id)
.then((user) => {
if (!user) {
return res.sendStatus(400);
}
return res.json({
user: user.toAuthJSON()
});
});
});
module.exports = router;
const jwt = require('express-jwt');
const getTokenFromHeaders = (req) => {
const {
headers: {
authorization
}
} = req;
if (authorization && authorization.split(' ')[0] === 'Token') {
return authorization.split(' ')[1];
}
return null;
};
const auth = {
required: jwt({
secret: 'secret',
userProperty: 'payload',
getToken: getTokenFromHeaders,
}),
optional: jwt({
secret: 'secret',
userProperty: 'payload',
getToken: getTokenFromHeaders,
credentialsRequired: false,
}),
};
module.exports = auth;
Это логика пользователей и аутентификации на моей стороне сервера с Node.
import React, { Component } from "react";
import { getJWT } from "../../helpers/jwt";
import axios from "axios";
import { withRouter } from "react-router";
export class Auth extends Component {
constructor(props) {
super(props);
this.state = {
user: undefined
};
}
componentDidMount() {
const jwt = getJWT();
if (!jwt) {
this.props.history.push("/Signup");
}
axios
.get("http://localhost:3000/api/users/current", {
headers: {
Authorization: `Token ${jwt}`
}
})
.then(res => {
console.log(res);
this.setState({
user: res.data.user
// user: {
// email: this.state.user.email,
// password: this.state.user.password
// }
});
console.log(this.setState);
})
.catch(err => {
console.log(err);
localStorage.removeItem("cool-jwt");
debugger;
this.props.history.push("/Protected");
});
}
render() {
if (this.state.user === undefined) {
return (
<div>
<h1> Loading... </h1>{" "}
</div>
);
}
return <div> {this.props.children} </div>;
}
}
export default withRouter(Auth);
Это моя авторизация во внешнем интерфейсе.
import React, { Component } from "react";
import Avatar from "@material-ui/core/Avatar";
import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import TextField from "@material-ui/core/TextField";
import Typography from "@material-ui/core/Typography";
import Container from "@material-ui/core/Container";
import Link from "@material-ui/core/Link";
import Grid from "@material-ui/core/Grid";
import { ValidatorForm, TextValidator } from "react-material-ui-form-validator";
import { classes } from "../constants/login";
import axios from "axios";
export class Signup extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
// repeatPassword: "",
errorText: ""
};
this.change = this.change.bind(this);
this.submit = this.submit.bind(this);
}
change(e) {
this.setState({
[e.target.name]: e.target.value
});
}
// componentDidMount() {
// // custom rule will have name 'isPasswordMatch'
// ValidatorForm.addValidationRule("isPasswordMatch", value => {
// if (value !== this.state.password) {
// return false;
// }
// return true;
// });
// }
// componentWillUnmount() {
// // remove rule when it is not needed
// ValidatorForm.removeValidationRule("isPasswordMatch");
// }
submit(e) {
e.preventDefault();
axios
.post("http://localhost:3000/api/users", {
user: {
email: this.state.email,
password: this.state.password
}
})
.then(res => {
debugger;
localStorage.setItem("cool-jwt", res.data.user.token);
console.log(res.data.user.token);
this.props.history.push("/Login");
});
}
render() {
return (
<div>
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar
alt="IPCA"
src="http://i68.tinypic.com/2gspvkm.png"
className={classes.bigAvatar}
/>{" "}
<Typography component="h1" variant="h5">
Sign up
</Typography>{" "}
<ValidatorForm
ref="form"
className={classes.form}
noValidate
onSubmit={e => this.submit(e)}
>
<TextValidator
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Insert your email"
name="email"
autoComplete="email"
autoFocus
onChange={e => this.change(e)}
value={this.state.email}
validators={["required"]}
errorMessages={["this field is required"]}
/>{" "}
<TextValidator
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Insert your Password"
type="password"
id="password"
autoComplete="current-password"
onChange={e => this.change(e)}
value={this.state.password}
onBlur={this.isDisabled}
validators={["required"]}
errorMessages={["this field is required"]}
/>{" "}
{/* <TextValidator
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Repeat your Password"
type="password"
id="password"
autoComplete="current-password"
onChange={e => this.change(e)}
value={this.state.repeatPassword}
onBlur={this.isDisabled}
validators={["isPasswordMatch", "required"]}
errorMessages={["password mismatch", "this field is required"]}
value={this.state.repeatPassword}
/>{" "} */}
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Submit{" "}
</Button>{" "}
</ValidatorForm>{" "}
</div>{" "}
</Container>{" "}
</div>
);
}
}
export default Signup;
Это моя регистрация, которая выглядит нормально, потому что токен остается в браузере, а пользователь хранится в Монго.
import React, { Component } from "react";
import Avatar from "@material-ui/core/Avatar";
import Button from "@material-ui/core/Button";
import CssBaseline from "@material-ui/core/CssBaseline";
import TextField from "@material-ui/core/TextField";
import Typography from "@material-ui/core/Typography";
import Container from "@material-ui/core/Container";
import Link from "@material-ui/core/Link";
import Grid from "@material-ui/core/Grid";
import { ValidatorForm, TextValidator } from "react-material-ui-form-validator";
import { classes } from "../constants/login";
import axios from "axios";
export class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: "",
password: "",
errorText: ""
};
this.change = this.change.bind(this);
this.submit = this.submit.bind(this);
}
change(e) {
this.setState({
[e.target.name]: e.target.value
});
}
submit(e) {
e.preventDefault();
axios
.get("http://localhost:3000/api/users/current", {
user: {
email: this.state.email,
password: this.state.password
}
})
.then(res => {
localStorage.setItem("cool-jwt", res.data.user.token);
console.log(res.data.user.token);
});
}
render() {
return (
<div>
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar
alt="IPCA"
src="http://i68.tinypic.com/2gspvkm.png"
className={classes.bigAvatar}
/>{" "}
<Typography component="h1" variant="h5">
Sign in
</Typography>{" "}
<ValidatorForm
ref="form"
className={classes.form}
noValidate
onSubmit={e => this.submit(e)}
>
<TextValidator
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
onChange={e => this.change(e)}
value={this.state.email}
validators={["required"]}
errorMessages={["this field is required"]}
/>{" "}
<TextValidator
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={e => this.change(e)}
value={this.state.password}
onBlur={this.isDisabled}
validators={["required"]}
errorMessages={["this field is required"]}
/>{" "}
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Submit{" "}
</Button>{" "}
<Grid container>
<Grid item xs>
<Link href="#" variant="body2">
Forgot password?
</Link>
</Grid>
<Grid item>
<Link href="#" variant="body2">
{"Don't have an account? Sign Up"}
</Link>
</Grid>
</Grid>
</ValidatorForm>{" "}
</div>{" "}
</Container>{" "}
</div>
);
}
}
export default Login;
При входе на эту конечную точку я получаю
Это трюк Форма входа, которая мне не дает с ошибкой
GET /api/users/current 401 0.995 ms - 139
UnauthorizedError: No authorization token was found
Заранее спасибо