Я использую React Context API для хранения информации о том, что пользователь аутентифицирован.
В режиме разработки, когда я ввожу любой URL-адрес, который перенаправляет на страницу ошибки 404, данные контекста теряются. Когда я перехожу на действительную страницу, ранее вошедший в систему пользователь больше не входит в систему.
Обновлено: Я только что проверил это с gatsby build и gatsby serve. Встроенный gatsby-сайт сохраняет контекст при перенаправлении на страницу с ошибкой 404. Но контекст по-прежнему теряется при переходе по совершенно другому URL-адресу, такому как www.google.com.
Теперь мой вопрос: как мне повторно предоставить контекст с информацией для входа без повторного входа пользователя в систему вручную?
Вот мой класс-оболочка AuthContextProvider:
export class AuthContextProvider extends React.Component {
constructor(props) {
super(props);
this.state = { user: {} };
}
// ...
render() {
return (
<AuthContext.Provider value = {{ getUser: this.getUser, setUser: this.setUser }}>
{this.props.children}
</AuthContext.Provider>
);
}
}
Я оборачиваю все свое приложение контекстным провайдером в корневой макет:
const RootLayout = ({ children }) => {
return (
<AuthContextProvider>
{children}
</AuthContextProvider>
);
}





React Context — это предоставление некоторых данных одному или нескольким дочерним компонентам без необходимости передачи данных через промежуточные компоненты. Нет встроенного механизма сохранения состояния между загрузками страниц, поэтому для этого вам понадобится другой инструмент.
Если вы еще не реализовали свой уровень аутентификации, вам нужно посмотреть, как это будет работать. Существует ряд стратегий для поддержания этого состояния, даже при использовании хранилища на основе файлов cookie. JWT (веб-токен JSON) — это популярный метод, который позволит вам хранить подписанные данные пользователя и данные, доступные для чтения клиентом, в файле cookie за счет того, что вам потребуется немного больше усилий для управления истечением срока действия/обновления и увеличения полезной нагрузки. Предполагая, что вы выбрали такой подход, вы можете сделать что-то вроде этого:
import React from "react";
import jwt from "jsonwebtoken"; // Add jsonwebtoken via npm/yarn
function getCookieValue(a) {
var b = document.cookie.match('(^|[^;]+)\\s*' + a + '\\s*=\\s*([^;]+)');
return b ? b.pop() : '';
}
const AUTH_PUBLIC_KEY = "your JWT public key here"
export const AuthContext = React.createContext();
export class AuthContextProvider extends React.Component {
state = {
authenticated: false,
userid: null,
};
componentDidMount() {
jwt.verify(getCookieValue("session"), AUTH_PUBLIC_KEY, (err, session) => {
if (!err && session.userid) {
this.setState({ userid: session.userid, authenticated: true })
}
})
}
// Important: REMOVE THIS AFTER TESTING/DEV
toggleLogin = () => {
this.setState(state => ({
authenticated: !state.authenticated,
userid: 2,
}));
}
render() {
return (
<AuthContext.Provider
value = {{
...this.state,
toggleLogin: this.toggleLogin,
}}
>
{this.props.children}
</AuthContext.Provider>
);
}
}
Это проанализирует токен JWT в файле cookie session при монтировании AuthContextProvider и обновит состояние значением userid, хранящимся в JWT, если оно присутствует.
Вероятно, вы захотите обернуть Гэтсби App этим компонентом, что вы можете сделать из файлов gatsby-browser.js и gatsby-ssr.js (создайте их в корне вашего репозитория, если у вас их еще нет):
// gatsby-browser.js
import React from "react"
import AuthContextProvider from "components/AuthContextProvider"
export const wrapRootElement = ({ element }) =>
<AuthContextProvider>{element}</AuthContextProvider>
// gatsby-ssr.js
import React from "react"
export { wrapRootElement } from "./gatsby-browser"
Вам по-прежнему нужно будет обрабатывать генерацию токена JWT (вероятно, из серверной части, которая обрабатывает аутентификацию), и если он еще не сохраняется в файле cookie, к которому вы можете получить доступ из браузера, вам нужно будет обработать создание этого файла cookie в соответствующий момент в жизненный цикл вашего приложения.
Я надеюсь, что это поможет вам или другим. В сообщении блога ниже описывается, как использовать gatsby-browser.js для переноса корневого элемента в провайдер, чтобы он не сбрасывал его при изменении страницы.
https://www.gatsbyjs.org/blog/2019-01-31-using-react-context-api-with-gatsby/
Отличное чтение о справочной информации — этот блог на dev.to.
Этот вариант считается наименее безопасным. Не сохраняйте здесь личные данные, такие как адреса электронной почты. Никогда не сохраняйте конфиденциальную информацию, такую как данные кредитной карты и тому подобное.
Этот вопрос описывает, как его использовать:
var testObject = { 'one': 1, 'two': 2, 'three': 3 };
// Put the object into storage
localStorage.setItem('testObject', JSON.stringify(testObject));
// Retrieve the object from storage
var retrievedObject = localStorage.getItem('testObject');
console.info('retrievedObject: ', JSON.parse(retrievedObject));
Для Express вы можете использовать express-ession. Другие веб-серверы имеют аналогичное промежуточное ПО. Суть в том, чтобы предоставить информацию о пользователе в файле cookie, как описано в МДН.
Это похоже на файлы cookie, но использует веб-токены JSON. @coreyward дал отличный ответ. Вы также можете прочитать больше в этот пост в блоге.