 
			
				03.07.2025, 10:29
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 27.11.2021 
					
					
					
						Сообщений: 108
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
			
			 
				Проблема с jwt
			 
			
		
		
		
		прошел курс по разработке интернет магазина на reacr node express postgress (sequelize) 
В конце препод все разжевывает но учащимся надо самим создать модуль корзины. Столкнулся со следующей проблемой, чтобы получить  все устройства добавленные в корзину надо знать userId кототрый содержится в jwt token-е, для чего я импортирую userController в basketController  чтобы расшифровать токен и вытянуть userId, но при импорте авторизация перестает работать что делать вот код: 
UserController.js
 
const ApiError = require('../error/ApiError');
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
const {User, Basket} = require('../models/models')
const generateJwt = (id, email, role) => {
    return jwt.sign(
        {id, email, role},
        process.env.SECRET_KEY,
        {expiresIn: '24h'}
    )
}
class UserController {
    async registration(req, res, next) {
        const {email, password, role} = req.body
        if (!email || !password) {
            return next(ApiError.badRequest('Некорректный email или password'))
        }
        const candidate = await User.findOne({where: {email}})
        if (candidate) {
            return next(ApiError.badRequest('Пользователь с таким email уже существует'))
        }
        const hashPassword = await bcrypt.hash(password, 5)
        const user = await User.create({email, role, password: hashPassword})
        const basket = await Basket.create({userId: user.id})
        const token = generateJwt(user.id, user.email, user.role)
        return res.json({token})
    }
    async login(req, res, next) {
        const {email, password} = req.body
        const user = await User.findOne({where: {email}})
        if (!user) {
            return next(ApiError.internal('Пользователь не найден'))
        }
        let comparePassword = bcrypt.compareSync(password, user.password)
        if (!comparePassword) {
            return next(ApiError.internal('Указан неверный пароль'))
        }
        const token = generateJwt(user.id, user.email, user.role)
        return res.json({token})
    }
    async check(req, res, next) {
        const token = generateJwt(req.user.id, req.user.email, req.user.role)
        return res.json({token})
    }
}
module.exports = new UserController()
basketController.js
 
const uuid = require('uuid')
const path = require('path');
const {Users,Basket, BasketDevice, User, Device} = require('../models/models')
const ApiError = require('../error/ApiError');
const {where} = require("sequelize");
const userController = require('./userController')
const jwt = require('jsonwebtoken')
class BasketController {
    async create(req, res, next) {
        try {
            let {deviceId} = req.body
            const generateJWT=userController.check;
            let usrId;
            jwt.verify(generateJWT,process.env.SECRET_KEY, function(err, decoded) {
                usrId=decoded[0];
            });
            const basket = await Basket.findOne({where: {userId:usrId}});
            const basketDevice = await BasketDevice.create({basketId: basket.id,deviceId:deviceId });
                return res.json(basket.id,basketDevice);
        } catch (e) {
            next(ApiError.badRequest(e.message))
        }
    }
    async getAll(req, res) {
        let usrId;
        const generateJWT=userController.check;
        jwt.verify(generateJWT,process.env.SECRET_KEY, function(err, decoded) {
            usrId=decoded[0];
        });
        const basket = await Basket.findOne({where: {userId:usrId}});
        const  basketDevices = await BasketDevice.findAndCountAll({where: {basketId:basket.id}});
        const bdevices={};
        basketDevices.map((bd)=>(
            bdevices.push(Devices.findOne({where: {id:bd.deviceId}}))
    ));
        return res.json(bdevices)
    }
}
module.exports = new BasketController()
 
		
	
		
		
		
		
		
		
	
		
			
			
	
			
			
			
			
			
				 
			
			
			
			
			
			
				
			
			
			
		 
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				03.07.2025, 10:52
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 CacheVar 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 19.08.2010 
					
					
					
						Сообщений: 14,298
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		Твой вариант 
	
 
	| 
		
			Сообщение от riaron86
			
		
	 | 
 
	
		
let usrId;
jwt.verify(generateJWT,process.env.SECRET_KEY, function(err, decoded) {
	usrId=decoded[0];
});
	 | 
 
	
 
 Не рабочий, т.к. асинхронный по природе... 
Предложу такой вариант
 
const usrId = await getId(jwt, generateJWT, process.env.SECRET_KEY)
 
Ну и сама функция...
 
// Получить ID пользователя
function getId(jwt, gen, key) {
	return new Promise((res, rej) => {
		jwt.verify(gen, key, (err, decoded) => {
			if (err) return rej(err)
			res(decoded[0])
		});
	})
}
 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				03.07.2025, 11:14
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Профессор 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 04.12.2012 
					
					
					
						Сообщений: 3,841
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		ksa, сигнатура  метода verify:
 
jwt.verify(token, secretOrPublicKey, [options, callback])
 
Там метод/функция генерирующий новый токен нафиг не нужен.  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				03.07.2025, 11:18
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 CacheVar 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 19.08.2010 
					
					
					
						Сообщений: 14,298
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	| 
		
			Сообщение от Nexus
			
		
	 | 
 
	| 
		Там метод/функция генерирующий новый токен нафиг не нужен.
	 | 
 
	
 
 По его коду, он так ИД пользователя получает...  
Но с таким синтаксисом присваивание сработает только после завершения всего метода  create...
 
На это я и обратил его внимание. Не более того...  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				03.07.2025, 11:25
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 27.11.2021 
					
					
					
						Сообщений: 108
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		выдает ту же ошибку, если делать по примеру ksa.(без импорта userController в  basketController код полностью рабочий как вытянуть токен из user controller не сбивая его работу?) 
←→1 of 3 errors on the page 
Unhandled Rejection (TypeError): Cannot read properties of undefined (reading 'data') 
click 
C:/online-store-full-course-master/client/src/pages/Auth.js:32 
  29 |         user.setIsAuth(true) 
  30 |         history.push(SHOP_ROUTE) 
  31 |     } catch (e) { 
> 32 |         alert(e.response.data.message) 
     | ^  33 |     } 
  34 |  
  35 | }
 
вот сам auth.js
 
import React, {useContext, useState} from 'react';
import {Container, Form} from "react-bootstrap";
import Card from "react-bootstrap/Card";
import Button from "react-bootstrap/Button";
import Row from "react-bootstrap/Row";
import {NavLink, useLocation, useHistory} from "react-router-dom";
import {LOGIN_ROUTE, REGISTRATION_ROUTE, SHOP_ROUTE} from "../utils/consts";
import {login, registration} from "../http/userAPI";
import {observer} from "mobx-react-lite";
import {Context} from "../index";
const Auth = observer(() => {
    const {user} = useContext(Context)
    const location = useLocation()
    const history = useHistory()
    const isLogin = location.pathname === LOGIN_ROUTE
    const [email, setEmail] = useState('')
    const [password, setPassword] = useState('')
    const click = async () => {
        try {
            let data;
            if (isLogin) {
                data = await login(email, password);
            } else {
                data = await registration(email, password);
            }
            user.setUser(user)
            user.setIsAuth(true)
            history.push(SHOP_ROUTE)
        } catch (e) {
            alert(e.response.data.message)
        }
    }
    return (
        <Container
            className="d-flex justify-content-center align-items-center"
            style={{height: window.innerHeight - 54}}
        >
            <Card style={{width: 600}} className="p-5">
                <h2 className="m-auto">{isLogin ? 'Авторизация' : "Регистрация"}</h2>
                <Form className="d-flex flex-column">
                    <Form.Control
                        className="mt-3"
                        placeholder="Введите ваш email..."
                        value={email}
                        onChange={e => setEmail(e.target.value)}
                    />
                    <Form.Control
                        className="mt-3"
                        placeholder="Введите ваш пароль..."
                        value={password}
                        onChange={e => setPassword(e.target.value)}
                        type="password"
                    />
                    <Row className="d-flex justify-content-between mt-3 pl-3 pr-3">
                        {isLogin ?
                            <div>
                                Нет аккаунта? <NavLink to={REGISTRATION_ROUTE}>Зарегистрируйся!</NavLink>
                            </div>
                            :
                            <div>
                                Есть аккаунт? <NavLink to={LOGIN_ROUTE}>Войдите!</NavLink>
                            </div>
                        }
                        <Button
                            variant={"outline-success"}
                            onClick={click}
                        >
                            {isLogin ? 'Войти' : 'Регистрация'}
                        </Button>
                    </Row>
                </Form>
            </Card>
        </Container>
    );
});
export default Auth;
вот еще   userApi если хотите посмотреть на полный принцип работы
 
import {$authHost, $host} from "./index";
import jwt_decode from "jwt-decode";
export const registration = async (email, password) => {
    const {data} = await $host.post('api/user/registration', {email, password, role: 'ADMIN'})
    localStorage.setItem('token', data.token)
    return jwt_decode(data.token)
}
export const login = async (email, password) => {
    const {data} = await $host.post('api/user/login', {email, password})
    localStorage.setItem('token', data.token)
    return jwt_decode(data.token,)
}
export const check = async () => {
    const {data} = await $authHost.get('api/user/auth' )
    localStorage.setItem('token', data.token)
    return jwt_decode(data.token)
}
 
		
	
		
		
		
		
		
		
	
		
			
			
	
			
			
			
			
			
				 
			
			
			
			
			
			
				
			
			
			
		 
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				03.07.2025, 11:28
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 27.11.2021 
					
					
					
						Сообщений: 108
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 нужен код стейт менеджера от  mobx-react-lite? 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				03.07.2025, 11:38
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 27.11.2021 
					
					
					
						Сообщений: 108
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		вот UserStore.js 
import {makeAutoObservable} from "mobx";
export default class UserStore {
    constructor() {
        this._isAuth = false
        this._user = {}
        makeAutoObservable(this)
    }
    setIsAuth(bool) {
        this._isAuth = bool
    }
    setUser(user) {
        this._user = user
    }
    get isAuth() {
        return this._isAuth
    }
    get user() {
        return this._user
    }
}
и индекс из userApi
 
import axios from "axios";
const $host = axios.create({
    baseURL: process.env.REACT_APP_API_URL
})
const $authHost = axios.create({
    baseURL: process.env.REACT_APP_API_URL
})
const authInterceptor = config => {
    config.headers.authorization = `Bearer ${localStorage.getItem('token')}`
    return config
}
$authHost.interceptors.request.use(authInterceptor)
export {
    $host,
    $authHost
}
 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				03.07.2025, 11:50
			
			
			
		  
	 | 
 
	
		
		
		
			  | 
			
			
				
				
				 CacheVar 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 19.08.2010 
					
					
					
						Сообщений: 14,298
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	
	
	
		
		
		
		
		
	
 
	| 
		
			Сообщение от riaron86
			
		
	 | 
 
	| 
		выдает ту же ошибку
	 | 
 
	
 
 Так судя по тексту ошибки, ты попадаешь на строку
 
	
 
	| 
		
			Сообщение от riaron86
			
		
	 | 
 
	
		
alert(e.response.data.message)
 
	 | 
 
	
 
 И там нет ключа  data...
 
Защититься можно так
 
alert(e.response?.data?.message ?? 'Какая-то фигня получилась')
  
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				03.07.2025, 12:36
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 27.11.2021 
					
					
					
						Сообщений: 108
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 без вызова функции check в  basketController все работает четко, в чем может быть причина и как мне вытащить данные из токена не обращаясь к check? 
 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
	
	
	
		
	
		
		
		
			
			 
			
				03.07.2025, 13:19
			
			
			
		  
	 | 
 
	
		
		
		
			
			| 
			
				
				
				 Кандидат Javascript-наук 
				
				
				
				
	
 
 
 
			 | 
			  | 
			
				
				
					Регистрация: 27.11.2021 
					
					
					
						Сообщений: 108
					 
					
					
			
		
 
		 
		
			 | 
		 
		 
		
	 | 
 
	| 
	
	
		
		
		
		
		 а так вставляя правильные данные о пользователе пользователь не логинится 
		
	
		
		
		
		
		
		
	
		
		
	
	
	 | 
 
 
	 
		 | 
 
 
 
 |  
  |