Проблема с 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() |
Твой вариант
Цитата:
Предложу такой вариант 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]) }); }) } |
ksa, сигнатура метода verify:
jwt.verify(token, secretOrPublicKey, [options, callback]) Там метод/функция генерирующий новый токен нафиг не нужен. |
Цитата:
Но с таким синтаксисом присваивание сработает только после завершения всего метода create... На это я и обратил его внимание. Не более того... |
выдает ту же ошибку, если делать по примеру 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) } |
нужен код стейт менеджера от mobx-react-lite?
|
вот 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 } |
Цитата:
Цитата:
Защититься можно так alert(e.response?.data?.message ?? 'Какая-то фигня получилась') |
без вызова функции check в basketController все работает четко, в чем может быть причина и как мне вытащить данные из токена не обращаясь к check?
|
а так вставляя правильные данные о пользователе пользователь не логинится
|
Часовой пояс GMT +3, время: 06:47. |