Итак, я следую руководству по полному стеку response / redux / mongodb.
Прямо сейчас я работаю над реализацией токенов для аутентификации пользователя и аутентификации маршрута и понятия не имею, как это работает.
Похоже, что учебник берет модель пользователя из папки моделей со стороны сервера. Если бы я развернул этот сайт, это вообще сработало бы? Я думал, что любое взаимодействие между интерфейсом и сервером может быть выполнено только через вызов api. 1007 *
Я что-то упускаю?
Я понятия не имею, в каком состоянии находится «пользователь». (<-Это то, что я пытаюсь выяснить) </p>
Побочные мысли / вопросы:
-Учебник делает это из-за наличия пользовательской модели в интерфейсе (которая может отображаться все типы данных (user_id, имя пользователя, пароль, адрес электронной почты и т. д. c)) могут представлять угрозу безопасности?
- Нужны ли вообще модели? Мне сказали, что они нужны вам для управления пользователями в серверной части. (Чтобы сервер мог различать от одного пользователя к другому). - Но нужна ли еще пользовательская модель для фронтенда? Разве вы не можете просто проверять токен при каждой ссылке / вызове?
Вот файлы:
Это панель управления пользователя (после того, как они вошли в систему). Я не понимаю, откуда взялся пользователь в const UserDashboard = ({user}) =>.
User/index.js
import React from 'react';
import UserLayout from '../../hoc/user';
import MyButton from '../utils/button';
import UserHistoryBlock from '../utils/User/history_block';
const UserDashboard = ({user}) => {
return (
<UserLayout>
<div>
<div className="user_nfo_panel">
<h1>User information</h1>
<div>
<span>{user.userData.name}</span>
<span>{user.userData.lastname}</span>
<span>{user.userData.email}</span>
</div>
<MyButton
type="default"
title="Edit account info"
linkTo="/user/user_profile"
/>
</div>
{
user.userData.history ?
<div className="user_nfo_panel">
<h1>History purchases</h1>
<div className="user_product_block_wrapper">
<UserHistoryBlock
products={user.userData.history}
/>
</div>
</div>
:null
}
</div>
</UserLayout>
);
};
export default UserDashboard;
Это макет панели управления пользователя. Это изменения кнопок панели навигации после того, как пользователь вошел в систему. Я не понимаю, откуда взялся user: state.user в mapStateToProps ().
hoc/user.js
import React from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
const links = [
{
name: 'My account',
linkTo: '/user/dashboard'
},
{
name: 'User information',
linkTo: '/user/user_profile'
},
{
name: 'My Cart',
linkTo: '/user/cart'
},
]
const admin = [
{
name: 'Site info',
linkTo: '/admin/site_info'
},
{
name: 'Add products',
linkTo: '/admin/add_product'
},
{
name: 'Manage categories',
linkTo: '/admin/manage_categories'
},
{
name: 'Upload file',
linkTo: '/admin/add_file'
}
]
const UserLayout = (props) => {
const generateLinks = (links) => (
links.map((item,i)=>(
<Link to={item.linkTo} key={i}>
{item.name}
</Link>
))
)
return (
<div className="container">
<div className="user_container">
<div className="user_left_nav">
<h2>My account</h2>
<div className="links">
{ generateLinks(links)}
</div>
{ props.user.userData.isAdmin ?
<div>
<h2>Admin</h2>
<div className="links">
{ generateLinks(admin)}
</div>
</div>
:null
}
</div>
<div className="user_right">
{props.children}
</div>
</div>
</div>
);
};
const mapStateToProps = (state) => {
return {
user: state.user
}
}
export default connect(mapStateToProps)(UserLayout);
Вот файл маршрутов, который использует панель управления пользователя в качестве маршрута с его входами. (Это первый маршрут)
routes.js
import React from 'react';
import { Switch, Route } from 'react-router-dom';
import Layout from './hoc/layout';
import Auth from './hoc/auth';
import Home from './components/Home';
import RegisterLogin from './components/Register_login';
import Register from './components/Register_login/register';
import Shop from './components/Shop';
import ProductPage from './components/Product';
import ResetUser from './components/Reset_user';
import ResetPass from './components/Reset_user/reset_pass';
import UserDashboard from './components/User';
import AddProduct from './components/User/Admin/add_product';
import ManageCategories from './components/User/Admin/manage_categories';
import UserCart from './components/User/cart';
import UpdateProfile from './components/User/update_profile';
import ManageSite from './components/User/Admin/manage_site';
import AddFile from './components/User/Admin/add_file';
import PageNotFound from './components/utils/page_not_found';
const Routes = () => {
return(
<Layout>
<Switch>
<Route path="/user/dashboard" exact component=
{Auth(UserDashboard,true)}/>
<Route path="/user/cart" exact component=
{Auth(UserCart,true)}/>
<Route path="/user/user_profile" exact component=
{Auth(UpdateProfile,true)}/>
<Route path="/admin/add_product" exact component=
{Auth(AddProduct,true)}/>
<Route path="/admin/manage_categories" exact component=
{Auth(ManageCategories,true)}/>
<Route path="/admin/site_info" exact component=
{Auth(ManageSite,true)}/>
<Route path="/admin/add_file" exact component={Auth(AddFile,true)}/>
<Route path="/reset_password/:token" exact component={Auth(ResetPass,false)}/>
<Route path="/reset_user" exact component={Auth(ResetUser,false)}/>
<Route path="/product_detail/:id" exact component={Auth(ProductPage,null)}/>
<Route path="/register" exact component={Auth(Register,false)}/>
<Route path="/register_login" exact component={Auth(RegisterLogin,false)}/>
<Route path="/shop" exact component={Auth(Shop,null)}/>
<Route path="/" exact component={Auth(Home,null)}/>
<Route component={Auth(PageNotFound)}/>
</Switch>
</Layout>
)
}
export default Routes;
Это файл аутентификации, который используется в маршрутах. И файл ./../models/user берется со стороны сервера.
auth.js
const { User } = require('./../models/user');
let auth = (req,res,next) => {
let token = req.cookies.w_auth;
User.findByToken(token,(err,user)=>{
if(err) throw err;
if(!user) return res.json({
isAuth: false,
error: true
});
req.token = token;
req.user = user;
next();
})
}
module.exports = { auth }
(Для справки, вот файл моделей / пользователя со стороны сервера)
/models/user.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const moment = require("moment");
const SALT_I = 10;
require('dotenv').config();
const userSchema = mongoose.Schema({
email:{
type:String,
required: true,
trim: true,
unique: 1
},
password:{
type:String,
required: true,
minlength: 5
},
name:{
type:String,
required: true,
maxlength:100
},
lastname:{
type:String,
required: true,
maxlength:100
},
cart:{
type:Array,
default: []
},
history:{
type:Array,
default: []
},
role:{
type:Number,
default:0
},
token:{
type:String
},
resetToken:{
type:String
},
resetTokenExp:{
type:Number
},
});
userSchema.pre('save',function(next){
var user = this;
if(user.isModified('password')){
bcrypt.genSalt(SALT_I,function(err,salt){
if(err) return next(err);
bcrypt.hash(user.password,salt,function(err,hash){
if(err) return next(err);
user.password = hash;
next();
});
})
} else{
next()
}
})
userSchema.methods.comparePassword = function(candidatePassword,cb){
bcrypt.compare(candidatePassword,this.password,function(err,isMatch){
if(err) return cb(err);
cb(null,isMatch)
})
}
userSchema.methods.generateResetToken = function(cb){
var user = this;
crypto.randomBytes(20,function(err,buffer){
var token = buffer.toString('hex');
var today = moment().startOf('day').valueOf();
var tomorrow = moment(today).endOf('day').valueOf();
user.resetToken = token;
user.resetTokenExp = tomorrow;
user.save(function(err,user){
if(err) return cb(err);
cb(null,user);
})
})
}
userSchema.methods.generateToken = function(cb){
var user = this;
var token = jwt.sign(user._id.toHexString(),process.env.SECRET)
user.token = token;
user.save(function(err,user){
if(err) return cb(err);
cb(null,user);
})
}
userSchema.statics.findByToken = function(token,cb){
var user = this;
jwt.verify(token,process.env.SECRET,function(err,decode){
user.findOne({"_id":decode,"token":token},function(err,user){
if(err) return cb(err);
cb(null,user);
})
})
}
const User = mongoose.model('User',userSchema);
module.exports = { User }
tl; dr: Итак, пользователь находится в состоянии, исходящем из файла / models / user с сервера? Разве это не сработает после развертывания?
Мы будем очень благодарны за любые предложения или иное.