Аполлон аутентификации с Гэтсби - PullRequest
0 голосов
/ 31 мая 2018

Я пытаюсь реализовать рабочий процесс Аутентификация , официально описанный в Документах Apollo , как я делал это ранее в других проектах, но на этот раз с использованием Гэтсби .

Идея кажется довольно простой.Необходимо создать / обновить gatsby-browser.js, как при использовании redux , но инициализировать ApolloClient и пройти через ApolloProvider.

Что-то вроде:

import React from 'react'
import { Router } from 'react-router-dom'
import { ApolloProvider } from 'react-apollo'
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { setContext } from 'apollo-link-context'

const httpLink = createHttpLink({
  uri: process.env.ENDPOINT_URI,
  credentials: 'same-origin',     
})

const authLink = setContext((_, { headers }) => {
  const token = localStorage.getItem('token');
  return {
    headers: {
      ...headers,
      authorization: token ? `Bearer ${token}` : "",
    }
  }
})

const client = new ApolloClient({
  link: authLink.concat(httpLink),
  cache: new InMemoryCache().restore({}),
})

exports.replaceRouterComponent = ({ history }) => {
  const ConnectedRouterWrapper = ({ children }) => (
    <ApolloProvider client={client}>
      <Router history={history}>{children}</Router>
    </ApolloProvider>
  )

  return ConnectedRouterWrapper
}

Затем войдите в систему, используя

<Mutation
  mutation={LOGIN_MUTATION}
  refetchQueries={[{ query: CURRENT_USER_QUERY }]}
>
  {/*...*/}
</Mutation>

и в другом Компоненте с чем-то вроде Status (где при входе в систему отображается x в противном случае y):

<Query query={CURRENT_USER_QUERY} fetchPolicy="network-only">
{/*...*/}
</Query>

Проблема

При такой конфигурации, когда логин получает data (таким образом, учетные данные в порядке), я сохраняю токен, полученный в localStorage, но Компонент * Status делает Query с предыдущим (пустым) token, поэтому показывает, что он вышел из системы, также делает что-то вроде history.push('/') после входа в систему.

Обновление страницы, так как элемент вlocalStorage был сохранен ранее, Статус отображается как зарегистрированный.

Ожидаемое поведение

Идея состоит в том, чтобы иметь статус компонент обновлен после входа в систему, избегая обновления страницы, поэтому я добавил refetchQueries={[{ query: CURRENT_USER_QUERY }]}.

Я пробовал некоторые вещиke pass props (не требуется, если я изменяю route и использую withRouter в компоненте Status ), но, похоже, поздно, Query был запущен без нового token.

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

Я считаю, что ваша проблема связана с тем, как определяются ссылки.IMO, AuthLink должен быть определен до HttpLink (как промежуточное ПО):

const client = new ApolloClient({
  link: ApolloLink.from([
    authLink,
    httpLink
  ]),
  cache: new InMemoryCache().restore({}),
})

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

0 голосов
/ 01 июня 2018

Основная проблема здесь, вероятно, заключается в том, что ваш Status компонент должен быть повторно обработан только после того, как токен сохранен в localStorage.В данный момент он, вероятно, перерисовывается слишком рано.

Вы можете попробовать обернуть свой Status компонент другим компонентом-оберткой и проверить существование токена перед рендерингом Status составная часть.

...