@Nikita1244
Anonymous

Почему refreshToken со значением undefined?

Здравствуйте! Делаю токенизацию. Столкнулся с такой проблемой. У меня почему-то не передается refresh-токен в функцию. Когда я хочу зарегистрироваться, сервер падает с ошибкой БД, которая гласит, что поле token обязательно. Но почему оно пустое? Непонятно. Пробовал консолить, в UserService возвращается токен из функции generateTokens():
Promise {
  {
    accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6IkRhZGFzYWRAZ21haWwuY29tIiwiYWRtaW4iOmZhbHNlLCJpZCI6IjYzMmFlN2Y4YmFhN2JiYmJkMDY2YTlmMiIsImlzQWN0aXZhdGVkIjpmYWxzZSwiaWF0IjoxNjYzNzU2MjgxLCJleHAiOjE2NjM3NTcxODF9.FjUFKmvsGMcHQfiKwSmt78O9UB7Q4R1iajy2C64DvlI',
    refreshToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6IkRhZGFzYWRAZ21haWwuY29tIiwiYWRtaW4iOmZhbHNlLCJpZCI6IjYzMmFlN2Y4YmFhN2JiYmJkMDY2YTlmMiIsImlzQWN0aXZhdGVkIjpmYWxzZSwiaWF0IjoxNjYzNzU2MjgxLCJleHAiOjE2NjYzNDgyODF9.ax355anK_a1uvhFQZlkHvBFpS_e4Eg5GHHTUr0LpCmo'
  }
}


Но когда я передаю значение рефреш-токена в функцию saveToken():
await TokenService.saveToken(userDto.id, tokens.refreshToken);

то почему-то я получаю в консоли undefined из функции saveToken(). В чем проблема?

код

Код UserService
const UserModel = require('../models/User')
const bcrypt = require('bcrypt')
const MailService = require('./MailService')
const TokenService = require('./TokenService')
const uuid = require('uuid');
const UserDto = require('../dtos/UserDto')

class UserService {
    async register(name, email, password) {
        const candidate = await UserModel.findOne({email})
        if (candidate) {
            throw new Error("Пользователь с такой почтой уже зарегистрирован")
        }
        const activationLink = uuid.v4(); // v34fa-asfasf-142saf-sa-asf

        const link = `https://localhost:8080/api/activate/${activationLink}`;
        const hash = await bcrypt.hash(password, 10)
        const user = await UserModel.create({
            name: name,
            email: email,
            password: hash,
            activationLink
        })
        await MailService.sendActivationCode(email, link)

        const userDto = new UserDto(user)
        const tokens = TokenService.generateTokens({...userDto});
        console.log(tokens)
        await TokenService.saveToken(userDto.id, tokens.refreshToken);
        return {...tokens, user: userDto}

    }

    async activate(activationLink) {
        const user = await UserModel.findOne(activationLink)
        if(!user) {
            throw new Error("Некорректная ссылка активации")
        }
        user.isActivated = true;
        await user.save()
    }

    async refresh(refreshToken) {
        if (!refreshToken) {
            throw new Error("Не авторизован")
        }
        const userData = TokenService.validateRefreshToken(refreshToken);
        const tokenFromDb = await TokenService.findToken(refreshToken);
        if (!userData || !tokenFromDb) {
            throw new Error("Не авторизован")
        }
        const user = await UserModel.findById(userData.id);
        const userDto = new UserDto(user);
        const tokens = TokenService.generateTokens({...userDto});

        await TokenService.saveToken(userDto.id, tokens.refreshToken);
        return {...tokens, user: userDto}
    }
}

module.exports = new UserService()


Код TokenService:
const jwt = require('jsonwebtoken');
const TokenModel = require('../models/Token');
const config = require('../config.json')
class TokenService {
    async generateTokens(payload) {
        const accessToken = jwt.sign(payload, config.SECRET_KEY_ACCESS_TOKEN, {expiresIn: '15m'})
        const refreshToken = jwt.sign(payload, config.SECRET_KEY_REFRESH_TOKEN, {expiresIn: '30d'})
        return {
            accessToken,
            refreshToken
        }
    }

    validateAccessToken(token) {
        try {
            return jwt.verify(token, config.SECRET_KEY_ACCESS_TOKEN);
        } catch (e) {
            return null;
        }
    }

    validateRefreshToken(token) {
        try {
            return jwt.verify(token, process.env.JWT_REFRESH_SECRET);
        } catch (e) {
            return null;
        }
    }

    async saveToken(userId, refreshToken) {
        const tokenData = await TokenModel.findOne({user: userId})
        if (tokenData) {
            tokenData.refreshToken = refreshToken;
            return tokenData.save();
        }
        const token = await TokenModel.create({user: userId, token: refreshToken})
        return token;
    }

    async removeToken(refreshToken) {
        return TokenModel.deleteOne({refreshToken});
    }

    async findToken(refreshToken) {
        return TokenModel.findOne({refreshToken});
    }
}

module.exports = new TokenService();


Код контроллера:
const UserService = require('../services/UserService')
class UserController {
    async register(req, res, next) {
        const { name, email, password } = req.body
        const userData = await UserService.register(name, email, password)
        res.cookie('refreshToken', userData.refreshToken, {MaxAge: 30 * 24 * 60 * 60 * 1000, httpOnly: true})
        console.log("User Controller" + userData)
        return res.json(userData)
    }

    async login(req, res, next) {

    }

    async logout(req, res, next) {

    }

    async refresh(req, res, next) {
        try {
            const {refreshToken} = req.cookies;
            const userData = await UserService.refresh(refreshToken);
            res.cookie('refreshToken', userData.refreshToken, {maxAge: 30 * 24 * 60 * 60 * 1000, httpOnly: true})
            return res.json(userData);
        } catch (e) {
            next(e);
        }
    }

    async activate(req, res, next) {
        try {
            const activationLink = req.params.link;
            await UserService.activate(activationLink);
            return res.redirect("/home");
        } catch (e) {
            next(e);
        }
    }
}

module.exports = new UserController()

  • Вопрос задан
  • 125 просмотров
Пригласить эксперта
Ответы на вопрос 1
@7rows
Frontend Разработчик / Vue / JS / TS / CSS
async generateTokens(payload) {
        const accessToken = await jwt.sign(payload, config.SECRET_KEY_ACCESS_TOKEN, {expiresIn: '15m'})
        const refreshToken = await jwt.sign(payload, config.SECRET_KEY_REFRESH_TOKEN, {expiresIn: '30d'})
        return {
            accessToken,
            refreshToken
        }
    }

Судя по документации, у вас там должна быть асинхронная функция,

Второй момент, вы должны зарезолвить пропис,
У вас скорее всего его вообще нет, а вы пытаетесь его передать
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы