Как реализовать защиту CSRF в Nextjs с помощью Apollo и GraphQL - PullRequest
0 голосов
/ 13 января 2019

Следуя этому примеру в репозитории Nextjs, я хочу реализовать защиту CSRF (возможно, с пакетом csurf ), потому что я использую cookie-файл идентификатора сеанса с express-session.

Я попытался установить csurf на моем пользовательском сервере и сохранить сгенерированный токен в res.locals.csrfToken, который можно получить при загрузке первой страницы статическим методом "getInitialProps", который находится в /lib/withApollo.js в пример, который я связал. Как только я пытаюсь изменить страницу (со ссылками) или сделать запрос на публикацию с помощью apollo (например, логин), сервер меняет токен csrf, поэтому тот, который использовался Apollo, больше не является полезным, и поэтому я получаю ошибка "csrf is invalid".

Пользовательский сервер с конфигурацией csurf

const csrf = require('csurf');
const csrfProtection = csrf();
////express-session configuration code////
app.use(csrfProtection);
app.use((req, res, next) => {
    res.locals.csrfToken = req.csrfToken();
next();
})

/ Библиотека / initApollo.js

function create(initialState, { getToken, cookies, csrfToken }) {
  const httpLink = createHttpLink({
    uri: "http://localhost:3000/graphql",
    credentials: "include"
  });

    const authLink = setContext((_, { headers }) => {
    const token = getToken();
    return {
      headers: {
        ...headers,
        authorization: token ? `Bearer ${token}` : "",
        Cookie: cookies ? cookies : "",
        "x-xsrf-token": csrfToken ? csrfToken : ""
      }
    };
  });

/ Библиотека / withApollo.js

static async getInitialProps(ctx) {
  const {
    Component,
    router,
    ctx: { req, res }
  } = ctx;
  const apollo = initApollo(
    {},
    {
      getToken: () => parseCookies(req).token,
      cookies: req ? req.headers.cookie : "",
      csrfToken: res ? res.locals.csrfToken : document.cookie
    }
  );

С помощью этой конфигурации каждый маршрут защищен от csrf, но токен, созданный на сервере, часто меняется, и Apollo не может получить обновленный токен, как только ему это нужно, поэтому первая загрузка прошла успешно, но последующее изменение страницы (ссылки) или любой пост-запрос завершается неудачно, потому что токен изменился.

Ответы [ 2 ]

0 голосов
/ 28 июля 2019

Обновление

После такого большого количества просмотров я наконец смог послать csrf cookie. Я думаю, что проблема связана со словом return. Когда вы используете return, он исключает cookie. Это то, что я сделал, отредактировав /lib/initApollo.js.


function create(initialState, { getToken, cookies, csrfToken }) {
  const httpLink = createHttpLink({
    uri: "http://localhost:3000/graphql",
    credentials: "include"
  });

    const authLink = setContext((_, { headers }) => {
    const token = getToken();
    return {
      headers: {
        ...headers,
        authorization: token ? `Bearer ${token}` : "",
        "x-xsrf-token": csrfToken ? csrfToken : ""
      }
      cookies: {
        ...cookies
      }
    };
  });

Pree !! Однако SSR не имеет куки. Я думаю, что у нас должно быть две конечные точки от клиента и еще одна для SSR. URL-адрес SSR может быть освобожден csrf.

0 голосов
/ 12 июля 2019

Возможно, это не тот ответ, который вы ищете. Я прочитал здесь , что если вы используете JWT, CSRFToken не нужен. Я не совсем уверен, но это только начало.

Бенджамин М объясняет следующее:

Я нашел некоторую информацию о CSRF +, не используя куки для аутентификации:

https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/ «поскольку вы не полагаетесь на файлы cookie, вам не нужно защищать от межсайтовых запросов»

http://angular -tips.com / блог / 2014/05 / JSON-веб-токенов введение / «Если мы пойдем по пути« куки », вам действительно нужно сделать CSRF, чтобы избежать межсайтовых запросов. Это то, что мы можем забыть при использовании JWT, как вы увидите». (JWT = Json Web Token, аутентификация на основе токенов для приложений без сохранения состояния)

http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services «Самый простой способ выполнить аутентификацию, не рискуя уязвимостями CSRF, - это просто избегать использования файлов cookie для идентификации пользователя»

http://sitr.us/2011/08/26/cookies-are-bad-for-you.html «Самая большая проблема с CSRF заключается в том, что файлы cookie не обеспечивают абсолютно никакой защиты от атак такого типа. Если вы используете проверку подлинности с помощью файлов cookie, вы должны также предпринять дополнительные меры для защиты от CSRF. приложение никогда не выполняет никаких побочных эффектов в ответ на запросы GET. "

Есть еще много страниц, в которых говорится, что вам не нужна защита от CSRF, если вы не используете куки для аутентификации. Конечно, вы все еще можете использовать куки для всего остального, но избегайте хранить в нем что-либо вроде session_id.

Полная статья здесь: Токен CSRF необходим при использовании аутентификации без состояния (= без сеанса)?

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