Лучший способ проверить доступ к маршруту - PullRequest
0 голосов
/ 19 апреля 2020

Моя установка такая: у меня есть интерфейс React, который делает запросы к серверу express (очевидно, на основе узла). Когда пользователь входит в систему, его учетные данные проверяются и, наконец, возвращается токен, который будет использоваться для выполнения дальнейших действий.

Так что это прекрасно работает, но я хочу запретить пользователям обходить экран входа в систему и просто сделать website.com/dashboard. Моей первой мыслью было проверять токен при каждом изменении маршрута в приложении, но я не знаю, правильно ли это делать.

Кажется, немного излишне совершать вызов каждый раз, когда изменения маршрута ... Но я не знаю, есть ли лучший способ сделать это. Просто проверить, существует ли токен, явно недостаточно, потому что пользователи могут просто поместить в него все, что они захотят.

Они не смогут вносить изменения или извлекать данные, потому что им нужен этот токен для отправки запросов к API, но все равно глупо, если вы можете просмотреть интерфейс, написав маршрут вручную.

Вот мои идеи по его устранению:

  • Выполнять вызов базы данных на каждом маршруте изменить, это, вероятно, не очень хорошая идея.
  • Сохраните токен в Redux и используйте его для выполнения вызовов. Если токена нет, просто перенаправьте на страницу входа. Это кажется довольно хорошим, но могут ли люди получить доступ к магазину редуксов из devtools или чего-то еще? Или это уже достаточно сложно, чтобы они не могли легко с этим связываться?

Ответы [ 2 ]

1 голос
/ 22 апреля 2020

Вы правы в том, как вы хотите это сделать. Вот еще одно объяснение:

То, о чем вы говорите, называется авторизацией (и отличается от аутентификации), которая обрабатывает то, что пользователь может получить доступ или нет. Вы можете проверить авторизацию различными способами.

Использование сеанса повара ie - это один из способов. Но ... поскольку вы создаете API, хорошей практикой является разделение внешнего интерфейса и внутреннего интерфейса (некоторые говорят "agnosti c"), что означает, что внешний интерфейс не должен ничего знать о внутреннем интерфейсе, и наоборот. -versa. Это делает использование сеанса cook ie не идеальным (поскольку у вас есть cook ie во внешнем интерфейсе, а информация о сеансе хранится в бэкэнде).

Таким образом, использование токена (JWT) хороший способ обработки авторизации.

В вашем случае вы действительно можете сначала аутентифицировать пользователя, а затем сохранить токен во внешнем интерфейсе.

Затем вы можете обрабатывать авторизацию следующим образом:

  1. Внешний интерфейс: отправьте маркер со всеми запросами, если он существует, в заголовке.

  2. Бэкэнд: проверьте токен. Если он действителен, пропустите пользователя. Если нет, отправьте сообщение об ошибке в веб-интерфейс!

  3. Если веб-интерфейс возвращает сообщение об ошибке, перенаправьте его в систему (или куда хотите).

Как ты это делаешь? (Я остановлюсь на бэкэнде. Там нет ничего, определяющего c во внешнем интерфейсе).

В вашем основном файле приложения (обычно app. js):

const express = require('express')

const publicRoutes = require('./routes/publicroutes')
const privateRoutes = require('./routes/privateroutes')

const defineAuth = require('./helpers/defineauth')
const isAuth = require('./helpers/isAuth')

const app = express()

app.use(defineAuth)

app.use('/publicRoute', publicRoutes) // like /login, /signup, etc...
app.use(isAuth)
app.use('/privateRoute', privateRoutes) // accessible only with a valid token

В defineAuth промежуточное ПО:

  1. Проверьте, существует ли заголовок авторизации

  2. Проверьте токен

    промежуточное ПО defineauth:

    const jwt = require('jsonwebtoken')
    module.exports = (req, res, next) => {
      const authHeader = req.get('Authorization')
      if (!authHeader) {
        req.isAuth = false
        return next()
      }
      const token = authHeader.split(' ')[1]
      let decodedToken
      try {
        decodedToken = jwt.verify(token, process.env.JWT_KEY)
      } catch (err) {
        req.isAuth = false
        return next()
      }
      if (!decodedToken) {
        req.isAuth = false
        return next()
      }
      // Here, the token is valid so :
      req.isAuth = true
      next()
    }
    

Тогда вы можете легко проверить в любом месте вашего кода, авторизован пользователь или нет. Здесь я проверяю приложение. js.

isAuth middleware : 
const isAuth = (req, res, next) => {
  if (!req.isAuth) {
    const error = new Error('Authorization required')
    error.status = 401
    throw error
  }
  next()
}

module.exports = isAuth

Вы можете подтвердить авторизацию где угодно. Таким образом, значительно упрощается работа с различными уровнями авторизации (если у вас есть, например, бесплатные и премиум-пользователи).

1 голос
/ 19 апреля 2020

Если вы используете express -сессию , при успешном входе в систему с идентификатором сеанса устанавливается повар ie с именем connect.sid . Вы можете прочитать значение этого идентификатора сеанса из cook ie в React, чтобы проверить, вошел ли пользователь в систему или нет, и соответствующим образом заблокировать запросы, не совершая вызовов API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...