Тайна модели пользователя - PullRequest
0 голосов
/ 26 мая 2020

Итак, я следую руководству по полному стеку 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 с сервера? Разве это не сработает после развертывания?

Мы будем очень благодарны за любые предложения или иное.

...