Обеспечение безопасности REST API с помощью подхода JWT access_token и refre sh token - PullRequest
0 голосов
/ 27 мая 2020

Я создаю веб-приложение, используя стек MERN. Я создал REST API для взаимодействия с моим интерфейсом обычным способом, но я не могу найти лучший способ создать безопасный API и общую безопасность приложения.

Пока это то, что я пробовал

Процесс аутентификации пользователя / запроса:
1. Пользователь вводит учетные данные
2. Сервер отвечает access_token и refresh_token, кэшируя refresh_token в кэше redis с адресом электронной почты в качестве ключа и access_token в localStorage
3. Для доступа к защищенному маршруту пользователь отправляет запрос с Bearer {ACCESS_TOKEN} в заголовке запроса
4. Сервер проверяет, действителен ли токен и не истек ли срок его действия , обслуживая пользователя обратно с помощью защищенного ресурса
5. В случае, если срок действия access_token истек (я оставил срок действия токена коротким, например, 5 минут), действие запускается из внешнего интерфейса (с использованием действий redux ), образец запроса:

POST http://localhost:3000/user/token
Header Bearer {ACCESS_TOKEN}
Body 
  {
     "email" : "user@example.com"
  }
Сервер выполняет проверку в кэше Redis, если в электронном письме указано refresh_token Если да, сервер отвечает обновленным access_token

Вот как я подписываю токенов

const signToken = user => {

    let email = user.email;
    let name = user.name;

    const accessToken = JWT.sign({
                            iss : process.env.APP_NAME,
                            sub : user.id,
                            email : email,
                            name : name
                        }, JWT_SECRET, {
                            expiresIn : 300
                        });

    const refreshToken = JWT.sign({
                                iss : process.env.APP_NAME,
                                sub : user.id,
                                email : email,
                                name : name
                            }, REFRESH_TOKEN_SECRET, {
                                expiresIn : '30d'
                            });

    // Save to redis cache
    REDIS_CLIENT.set(email, refreshToken);

    return {accessToken, refreshToken};
}

и для получения новых access_token

// Refresh token
const refreshToken = (req, res, next) => {

    const extractToken = req.headers['authorization'];
    const token = extractToken.split(' ')[1];

    if (!token) {
        return res.status(403).json({
            message : 'Unauthorized'
        });
    }

    REDIS_CLIENT.get(req.body.email, (err, cachedToken) => {
        if (err) return res.status(500).json({message : 'Something went wrong'});

        if (cachedToken == null) {
            return res.status(403).json({message : 'Unauthroized'});
        } else {

            JWT.verify(cachedToken, REFRESH_TOKEN_SECRET, (err, rt) => {
                if (err) {
                    return res.status(500).json({message : 'Something went wrong'})
                } else {
                    // Generate a new access token here
                    const newAccessToken = JWT.sign({
                                iss : process.env.APP_NAME,
                                sub : rt.sub,
                                email : rt.email,
                                name : rt.name
                            }, JWT_SECRET, {
                                expiresIn : 300
                            });

                    return res.json({
                        "accessToken" : newAccessToken
                    });
                }

            });

        }
    });
}

Безопасен ли этот подход? Если нет, каковы хорошие способы разработать поток аутентификации, если стек равен MERN. При поиске в inte rnet многие советовали установить короткий срок действия в access_token и использовать refresh_token для создания нового access_token, но я не нашел, как выйти из системы при бездействии? Что, если злоумышленник получит просроченный токен и идентификатор электронной почты и сгенерирует новый access_token? Как будет интеграция oAuth?

PS: Извините за то, что выложил здесь так много, зашел сюда после множества поисков по inte rnet, но ничего особенного не нашел

...