{"id":327150,"date":"2022-01-10T08:46:48","date_gmt":"2022-01-10T08:46:48","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=327150"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=327150","title":{"rendered":"<span>React: \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Auth0 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438\/\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\" class=\"article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/pu\/no\/zh\/punozh3zkth3cqyppf_przd5wco.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 (\u0434\u0430\u043b\u0435\u0435 \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0435\u0440\u0432\u0438\u0441) \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/auth0.com\/\"><code>Auth0<\/code><\/a>.<\/p>\n<p>  <\/p>\n<p><code>Auth0<\/code> \u2014 \u044d\u0442\u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438. <code>Auth0<\/code> \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439, \u0441\u0442\u043e\u044f\u0449\u0435\u0439 \u0437\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 <a href=\"https:\/\/jwt.io\/\"><code>JWT<\/code><\/a> (JSON Web Token\/\u0432\u0435\u0431-\u0442\u043e\u043a\u0435\u043d \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>JSON<\/code>). \u042d\u0442\u043e \u0432\u0441\u0435\u043b\u044f\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 <code>Auth0-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0411\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f <code>Auth0<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e 7000 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<p>  <\/p>\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/company\/timeweb\/blog\/593063\/\">\u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u044f \u043f\u0438\u0441\u0430\u043b \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 <code>JWT<\/code>, \u0438 \u043a\u0430\u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0441 \u043d\u0443\u043b\u044f.<\/p>\n<p>  <\/p>\n<p>\u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 <code>Auth0<\/code> \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0430\u0442\u044c <a href=\"https:\/\/auth0.com\/docs\/get-started\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 <code>Auth0 SDK<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/auth0\/auth0-react\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c, \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f <a href=\"https:\/\/github.com\/harryheman\/Blog-Posts\/tree\/master\/react-auth0\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043e \u0441\u0430\u043c\u044b\u0445 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u0445, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 <code>Auth0<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0438 \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430\u0445 \u043d\u0438\u0436\u0435 \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 <code>\u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\/sensitive data<\/code>. \u042d\u0442\u043e \u043d\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041f\u043e\u0441\u043b\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"podgotovka-i-nastroyka-proekta\">\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h2>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043d\u0435\u0435 \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u2014 \u0448\u0430\u0431\u043b\u043e\u043d <code>React\/TypeScript-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/create-react-app.dev\/\"><code>Create React App<\/code><\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">mkdir react-auth0 cd react-auth0 # cd !$  yarn create react-app client --template typescript # or npx create-react-app ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043d\u0435\u0435 \u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c <code>Node.js-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">mkdir server cd server  yarn init -yp # or npm init -y<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u043a\u043a\u0430\u0443\u043d\u0442 <code>Auth0<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/5i\/5f\/ql\/5i5fqlahehtnx1jsft1crjddthq.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c <code>tenant\/\u0430\u0440\u0435\u043d\u0434\u0430\u0442\u043e\u0440\u0430<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/sb\/rk\/1r\/sbrk1rvpiehuekqa-hbhsxfnnpu.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c <code>\u043e\u0434\u043d\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\/single page application<\/code> \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0435 <code>Applications\/Applications<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/l0\/bz\/pj\/l0bzpjs4f5z57freyy3njnlhuva.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/px\/1z\/7u\/px1z7upqylxmjizp3x_6hkphoam.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b <code>Settings<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/3x\/pj\/l2\/3xpjl22zirt03a0g32p0om1ub3g.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b <code>.env<\/code> \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>client<\/code> \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0432 \u043d\u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0439 <code>Domain<\/code> \u0438 <code>Client ID<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">REACT_APP_AUTH0_DOMAIN = auth0-test-app.eu.auth0.com REACT_APP_AUTH0_CLIENT_ID = Ykv47YaNC3naGvfljFt8LyhzVPRPZCJY<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c <code>URL<\/code> \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432 \u043f\u043e\u043b\u044f\u0445 <code>Allowed Callback URLs<\/code>, <code>Allowed Logout URLs<\/code> \u0438 <code>Allowed Web Origins<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/7m\/hp\/ka\/7mhpka12ziyvz_rycyipobultmu.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c <code>API<\/code> \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0435 <code>Applications\/API<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/r9\/ft\/re\/r9ftreme8ttk7g-kyndnl-ypwks.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/pl\/bu\/gg\/plbuggvxf-9qphw5ftrao6hrzeu.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b <code>Settings<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/kh\/ck\/or\/khckorhccaxme5qgbkasstggmim.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f <code>Identifier<\/code> \u0438 <code>URL<\/code> \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 \u0444\u0430\u0439\u043b <code>.env<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">REACT_APP_AUTH0_AUDIENCE='https:\/\/auth0-test-app' REACT_APP_SERVER_URI='http:\/\/localhost:4000\/api'<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0430\u0439\u043b <code>.env<\/code> \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>server<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">AUTH0_DOMAIN='auth0-test-app.eu.auth0.com' AUTH0_AUDIENCE='https:\/\/auth0-test-app' CLIENT_URI='http:\/\/localhost:3000'<\/code><\/pre>\n<p>  <\/p>\n<h2 id=\"klient\">\u041a\u043b\u0438\u0435\u043d\u0442<\/h2>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <code>client<\/code> \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\">cd client  # \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d\u0430 yarn add @auth0\/auth0-react react-router-dom react-loader-spinner # \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 yarn add -D sass<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/@auth0\/auth0-react\">@auth0\/auth0-react<\/a> \u2014 <code>Auth0 SDK<\/code> \u0434\u043b\u044f <code>React-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439<\/code><\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/react-router-dom\">react-router-dom<\/a> \u2014 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/react-loader-spinner\">react-loader-spinner<\/a> \u2014 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438<\/li>\n<li><a href=\"https:\/\/sass-lang.com\/\">sass<\/a> \u2014 <code>CSS-\u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440<\/code><\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>src<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">- api  - messages.ts - components  - AuthButton    - LoginButton      - LoginButton.tsx    - LogoutButton      - LogoutButton.tsx    - AuthButton.tsx  - Boundary    - Error      - error.scss      - Error.tsx    - Spinner      - Spinner.tsx    - Boundary.tsx  - Navbar    - Navbar.tsx - pages  - AboutPage    - AboutPage.tsx  - HomePage    - HomePage.tsx  - MessagePage    - message.scss    - MessagePage.tsx  - ProfilePage    - profile.scss    - ProfilePage.tsx - providers  - AppProvider.tsx  - Auth0ProviderWithNavigate.tsx - router  - AppRoutes.tsx  - AppLinks.tsx - styles  - _mixins.scss  - _variables.scss - types  - index.d.ts - utils  - createStore.tsx - App.scss - App.tsx - index.tsx ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0432 \u043f\u0430\u043d\u0435\u043b\u0438 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043a\u043d\u043e\u043f\u043a\u0430 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438;<\/li>\n<li>\u043a\u043d\u043e\u043f\u043a\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u0441\u044f \u0443\u0441\u043b\u043e\u0432\u043d\u043e \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f;<\/li>\n<li>\u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d, \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u043e\u043d \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <code>Auth0<\/code> \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443;<\/li>\n<li>\u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d, \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b;<\/li>\n<li>\u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0438\u043c\u0435\u0435\u0442\u0441\u044f 4 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b: <code>HomePage<\/code>, <code>AboutPage<\/code>, <code>ProfilePage<\/code> \u0438 <code>MessagePage<\/code>;<\/li>\n<li>\u043f\u0435\u0440\u0432\u044b\u0435 \u0434\u0432\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435;<\/li>\n<li>\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0434\u0432\u0435 \u2014 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438;<\/li>\n<li>\u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 <code>ProfilePage<\/code>, \u043e\u043d \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 <code>Auth0<\/code>;<\/li>\n<li>\u043f\u043e\u0441\u043b\u0435 \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 <code>ProfilePage<\/code>, \u0433\u0434\u0435 \u0432\u0438\u0434\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0441\u0432\u043e\u0435\u043c \u043f\u0440\u043e\u0444\u0438\u043b\u0435;<\/li>\n<li>\u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 <code>MessagePage<\/code> \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0434\u0432\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443: \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f;<\/li>\n<li>\u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d, \u043f\u0440\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u044f \u0431\u0443\u0434\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e <code>Auth0<\/code>.<\/p>\n<p>  <\/p>\n<p><strong>\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 <code>Auth0<\/code><\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 <code>Auth0<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 <code>Auth0Provider<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e\u0441\u043b\u0435 \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0430\u043f\u0433\u0440\u0435\u0439\u0434\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c (<code>providers\/Auth0ProviderWithNavigate<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0439 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 import { Auth0Provider } from '@auth0\/auth0-react' \/\/ \u0445\u0443\u043a \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0439 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 import { useNavigate } from 'react-router-dom' import { Children } from 'types'  const domain = process.env.REACT_APP_AUTH0_DOMAIN as string const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID as string const audience = process.env.REACT_APP_AUTH0_AUDIENCE as string  const Auth0ProviderWithNavigate = ({ children }: Children) => {  const navigate = useNavigate()   \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u0430\u044f \u043f\u043e\u0441\u043b\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438  const onRedirectCallback = (appState: { returnTo?: string }) => {    \/\/ \u043f\u0443\u0442\u044c \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0435 `returnTo`    \/\/ \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443    navigate(appState?.returnTo || window.location.pathname)  }   return (    &lt;Auth0Provider      domain={domain}      clientId={clientId}      \/\/ \u0434\u0430\u043d\u043d\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0443\u0436\u043d\u0430 \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c      audience={audience}      redirectUri={window.location.origin}      onRedirectCallback={onRedirectCallback}    >      {children}    &lt;\/Auth0Provider>  ) }  export default Auth0ProviderWithNavigate<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u043e\u0439 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f <a href=\"https:\/\/github.com\/auth0\/auth0-react\/blob\/master\/src\/auth0-provider.tsx\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 (<code>index.tsx<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import React from 'react' import ReactDOM from 'react-dom' import { BrowserRouter } from 'react-router-dom' import Auth0ProviderWithNavigate from 'providers\/Auth0ProviderWithNavigate' import { AppProvider } from 'providers\/AppProvider' import App from '.\/App'  ReactDOM.render(  &lt;React.StrictMode>    {\/* \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 *\/}    &lt;BrowserRouter>      {\/* \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 *\/}      &lt;Auth0ProviderWithNavigate>        {\/* \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f *\/}        &lt;AppProvider>          &lt;App \/>        &lt;\/AppProvider>      &lt;\/Auth0ProviderWithNavigate>    &lt;\/BrowserRouter>  &lt;\/React.StrictMode>,  document.getElementById('root') )<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0412\u0445\u043e\u0434 \u0438 \u0432\u044b\u0445\u043e\u0434 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <code>loginWithRedirect<\/code>, \u0430 \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u2014 \u043c\u0435\u0442\u043e\u0434 <code>logout<\/code>. \u041e\u0431\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0445\u0443\u043a\u043e\u043c <code>useAuth0<\/code>. <code>useAuth0<\/code> \u0442\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>isAuthenticated<\/code> (\u0438 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e \u0435\u0449\u0435) \u2014 \u0441\u0442\u0430\u0442\u0443\u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043a\u043d\u043e\u043f\u043e\u043a.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0430 \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 (<code>components\/AuthButton\/AuthButton.tsx<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0445\u0443\u043a import { useAuth0 } from '@auth0\/auth0-react' import { LoginButton } from '.\/LoginButton\/LoginButton' import { LogoutButton } from '.\/LogoutButton\/LogoutButton'  export const AuthButton = () => {  \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438  const { isAuthenticated } = useAuth0()   return isAuthenticated ? &lt;LogoutButton \/> : &lt;LoginButton \/> }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043d\u043e\u043f\u043a\u0430 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 (<code>components\/AuthButton\/LoginButton\/LoginButton.tsx<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0445\u0443\u043a import { useAuth0 } from '@auth0\/auth0-react'  export const LoginButton = () => {  \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443  const { loginWithRedirect } = useAuth0()   return (    &lt;button className='auth login' onClick={loginWithRedirect}>      Log In    &lt;\/button>  ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043d\u043e\u043f\u043a\u0430 \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b (<code>components\/AuthButton\/LogoutButton\/LogoutButton.tsx<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0445\u0443\u043a import { useAuth0 } from '@auth0\/auth0-react'  export const LogoutButton = () => {  \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b  const { logout } = useAuth0()   return (    &lt;button      className='auth logout'      \/\/ \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443      onClick={() => logout({ returnTo: window.location.origin })}    >      Log Out    &lt;\/button>  ) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u043e\u0439 \u0445\u0443\u043a\u0430 \u043c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f <a href=\"https:\/\/github.com\/auth0\/auth0-react\/blob\/master\/src\/use-auth0.tsx\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p><strong>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438<\/strong><\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0436\u0438\u0437\u043d\u0438 <code>id_token\/\u0442\u043e\u043a\u0435\u043d\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/code>. \u0412\u0440\u0435\u043c\u044f \u0436\u0438\u0437\u043d\u0438 \u0442\u043e\u043a\u0435\u043d\u0430 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0435 <code>Settings<\/code> \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u043f\u043e\u043b\u0435 <code>ID Token Expiration<\/code> \u0440\u0430\u0437\u0434\u0435\u043b\u0430 <code>ID Token<\/code> \u0438 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 <code>36 000<\/code> \u0441\u0435\u043a\u0443\u043d\u0434 \u0438\u043b\u0438 <code>10<\/code> \u0447\u0430\u0441\u043e\u0432:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/xp\/35\/_i\/xp35_i4pfioforsubevgbnncwva.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0422\u043e\u043a\u0435\u043d \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u0443\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 <code>Storage\/Cookies<\/code> \u0432\u043a\u043b\u0430\u0434\u043a\u0438 <code>Application<\/code> \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/kq\/rd\/i8\/kqrdi8x1q2fwojxs6wec0bxg9cg.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0441\u0442\u0430\u0442\u0443\u0441 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0438\/\u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0438 \u0432\u043a\u043b\u0430\u0434\u043a\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0438 \u0442.\u0434.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043a\u0443\u043a\u0438 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 <code>id_token<\/code> \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f.<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/d_\/o7\/qw\/d_o7qwb9ya8jnehkxbw-jeicw1g.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p><strong>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/strong><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 <code>withAuthenticationRequired<\/code>. \u0425\u0443\u043a <code>useAuth0<\/code>, \u043a\u0440\u043e\u043c\u0435 \u043f\u0440\u043e\u0447\u0435\u0433\u043e, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 <code>user<\/code> \u0441 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 <code>ProfilePage<\/code> \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c (<code>pages\/ProfilePage\/ProfilePage.tsx<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import '.\/profile.scss' import { useAuth0, withAuthenticationRequired } from '@auth0\/auth0-react' import { Spinner } from 'components\/index.components'  \/\/ \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043a\u043e\u0434 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 export const ProfilePage = withAuthenticationRequired(  () => {    \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f    const { user } = useAuth0()     return (      &lt;>        &lt;h1>Profile Page&lt;\/h1>        &lt;div className='profile'>          &lt;img src={user?.picture} alt={user?.name} \/>          &lt;div>            &lt;h2>{user?.name}&lt;\/h2>            &lt;p>{user?.email}&lt;\/p>          &lt;\/div>        &lt;\/div>      &lt;\/>    )  },  {    \/\/ \u043e\u0431\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u043c\u0438    returnTo: '\/profile',    onRedirecting: () => &lt;Spinner \/>  } )<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u043c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f <a href=\"https:\/\/github.com\/auth0\/auth0-react\/blob\/master\/src\/with-authentication-required.tsx\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p><strong>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430<\/strong><\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0445\u043e\u0434\u044f\u0441\u044c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <code>client<\/code>, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443 <code>yarn start<\/code> \u0438\u043b\u0438 <code>npm start<\/code> \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/pg\/yc\/kb\/pgyckb5mcyibw4-oad_hciyzshm.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Log In<\/code>. \u041f\u043e\u043f\u0430\u0434\u0430\u0435\u043c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438\/\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 <code>Auth0<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/bb\/h-\/17\/bbh-17pwf7igs-vuang03zopvfg.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 <code>Google<\/code> (<code>Google OAuth 2.0<\/code>). \u041f\u043e\u0437\u0436\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0430 <code>GitHub<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0412\u0445\u043e\u0434\u0438\u043c \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443. \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443. \u0412\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043a\u043d\u043e\u043f\u043a\u0430 <code>Log In<\/code> \u0441\u043c\u0435\u043d\u0438\u043b\u0430\u0441\u044c \u043a\u043d\u043e\u043f\u043a\u043e\u0439 <code>Log Out<\/code>.<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/pm\/2y\/2m\/pm2y2mrvzrk1udoe8fpl0j8mfwc.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0412\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 <code>Profile<\/code>. \u0421\u043d\u043e\u0432\u0430 \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u043c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 <code>Auth0<\/code>. \u0412\u0445\u043e\u0434\u0438\u043c \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443. \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u0440\u043e\u0444\u0438\u043b\u044f:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/eq\/rl\/vb\/eqrlvbavghkwelyjinezduf1kwm.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p><em>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 <code>GitHub<\/code><\/em><\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0432\u043a\u043b\u0430\u0434\u043a\u0443 <code>Authentication\/Social<\/code> \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 <code>Create Connection<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/ir\/qv\/g2\/irqvg29ro93oowiiob88izp9vao.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c <code>GitHub<\/code> \u0438\u0437 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/ro\/lc\/dl\/rolcdlcrkbajuczyg8e0umedbsg.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u043c \u0432 \u043f\u0440\u043e\u0444\u0438\u043b\u044c <code>GitHub<\/code>. \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b <code>Settings\/Developer settings\/OAuth Apps<\/code> \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Register a new application<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/7g\/-y\/ca\/7g-ycakozleshazjilnlot-6vok.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043f\u043e\u043b\u044f <code>Application name<\/code>, <code>Homepage URL<\/code> (<code>https:\/\/\u0412\u0410\u0428-\u0414\u041e\u041c\u0415\u041d.auth0.com<\/code>) \u0438 <code>Authorization callback URL<\/code> (<code>https:\/\/\u0412\u0410\u0428-\u0414\u041e\u041c\u0415\u041d\/login\/callback<\/code>):<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/kq\/uy\/sj\/kquysjugt9hh-tegqd00vtilm4k.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Generate a new client secret<\/code>. \u041a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0439 <code>Client ID<\/code> \u0438 <code>Client secret<\/code> \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043b\u044f <code>Auth0<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/gn\/lj\/xf\/gnljxfh_fdsi0pxk-vwgimaleag.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/jr\/aj\/yc\/jrajycahagf5etp7sumeftnabng.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 <code>Attributes<\/code> \u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a <code>Basic Profile<\/code> \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c <code>Email address<\/code>, \u0430 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 <code>Permissions<\/code> \u2014 <code>read:user<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Create<\/code>. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 <code>API<\/code>.<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/pg\/-5\/nk\/pg-5nkmgvqsgvp874mdwb2rpw0k.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Try Connection<\/code> \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 <code>Authorize \u0412\u0410\u0428\u0415_\u0418\u041c\u042f<\/code>.<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/8d\/jv\/g9\/8djvg9lxanbqkuy67y757ll2l8q.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/mq\/ze\/lh\/mqzelh57zqadbvfqma5eeaemxos.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0435\u0441\u043b\u0438 \u043c\u044b \u043d\u0430\u0436\u043c\u0435\u043c <code>Log In<\/code> \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>GitHub<\/code>:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/y8\/pw\/aw\/y8pwaw6qmfzxoozjllx5qqh0zt8.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f <code>Google<\/code>, \u0442\u043e <code>Auth0<\/code> \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u043a\u043b\u044e\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0437\u0430\u043c\u0435\u043d\u0435\u043d\u044b \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u043c\u0438 \u043f\u0435\u0440\u0435\u0434 \u0432\u044b\u043f\u0443\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d.<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439 <code>MessagePage<\/code> \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c.<\/p>\n<p>  <\/p>\n<h2 id=\"integraciya-klienta-s-serverom\">\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c<\/h2>\n<p>  <\/p>\n<p><strong>API<\/strong><\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 <code>API<\/code> (<code>api\/messages.ts<\/code>):<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">\/\/ \u0430\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 const SERVER_URI = process.env.REACT_APP_SERVER_URI  \/\/ \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f export async function getPublicMessage() {  let data = { message: '' }  try {    const response = await fetch(`${SERVER_URI}\/messages\/public`)    if (!response.ok) throw response    data = await response.json()  } catch (e) {    throw e  } finally {    return data.message  } }  \/\/ \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 `access_token\/\u0442\u043e\u043a\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f\u0430` export async function getProtectedMessage(token: string) {  let data = { message: '' }  try {    const response = await fetch(`${SERVER_URI}\/messages\/protected`, {      headers: {        \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0441 \u0442\u043e\u043a\u0435\u043d\u043e\u043c        Authorization: `Bearer ${token}`      }    })    if (!response.ok) throw response    data = await response.json()  } catch (e) {    throw e  } finally {    return data.message  } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 <code>MessagePage<\/code> (<code>pages\/MessagePage\/MessagePage.tsx<\/code>).<\/p>\n<p>  <\/p>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0445\u0443\u043a\u0438, \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440, \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u0441\u0442\u0438\u043b\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { useAuth0 } from '@auth0\/auth0-react' import { getProtectedMessage, getPublicMessage } from 'api\/messages' import { Boundary } from 'components\/Boundary\/Boundary' import { useAppSetter } from 'providers\/AppProvider' import { useState } from 'react' import '.\/message.scss'<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0435\u0442\u0442\u0435\u0440\u044b, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u0435\u0433\u043e \u0442\u0438\u043f\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const MessagePage = () => {  const { setLoading, setError } = useAppSetter()  const [message, setMessage] = useState('')  const [type, setType] = useState('')   \/\/ TODO }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0442\u043e\u043a\u0435\u043d\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 (<code>access_token<\/code>) \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u043c\u0435\u0442\u043e\u0434 <code>getAccessTokenSilently<\/code>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0445\u0443\u043a\u043e\u043c <code>useAuth0<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">const { getAccessTokenSilently } = useAuth0()<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function onGetPublicMessage() {    setLoading(true)    getPublicMessage()      .then(setMessage)      .catch(setError)      .finally(() => {        setType('public')        setLoading(false)      })  }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">function onGetProtectedMessage() {    setLoading(true)    \/\/ \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0443 `getProtectedMessage`    getAccessTokenSilently()      .then(getProtectedMessage)      .then(setMessage)      .catch(setError)      .finally(() => {        setType('protected')        setLoading(false)      })  }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">return (  &lt;Boundary>    &lt;h1>Message Page&lt;\/h1>    &lt;div className='message'>      &lt;button onClick={onGetPublicMessage}>Get Public Message&lt;\/button>      &lt;button onClick={onGetProtectedMessage}>Get Protected Message&lt;\/button>      {message &amp;&amp; &lt;h2 className={type}>{message}&lt;\/h2>}    &lt;\/div>  &lt;\/Boundary> )<\/code><\/pre>\n<p>  <\/p>\n<p><strong>\u0421\u0435\u0440\u0432\u0435\u0440<\/strong><\/p>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <code>server<\/code> \u0438 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"bash\"># \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u043d\u0430 yarn add express helmet cors dotenv express-jwt jwks-rsa # \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 yarn add -D nodemon<\/code><\/pre>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/expressjs.com\/ru\/\"><code>express<\/code><\/a>: <code>Node.js-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a<\/code> \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432;<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/helmet\"><code>helmet<\/code><\/a>: \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 <code>HTTP-\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432<\/code>, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c\u044e. \u041e\u0431 \u044d\u0442\u0438\u0445 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/github.com\/harryheman\/React-Total\/blob\/main\/md\/security\/security.md\">\u0437\u0434\u0435\u0441\u044c<\/a>;<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/cors\"><code>cors<\/code><\/a>: \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 <code>HTTP-\u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u0432<\/code>, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441 <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/HTTP\/CORS\"><code>CORS<\/code><\/a>;<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/dotenv\"><code>dotenv<\/code><\/a>: \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0441\u0440\u0435\u0434\u044b \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f;<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/express-jwt\"><code>express-jwt<\/code><\/a>: <code>\u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\/middleware<\/code> \u0434\u043b\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 <code>JWT<\/code> \u0447\u0435\u0440\u0435\u0437 \u043c\u043e\u0434\u0443\u043b\u044c <a href=\"https:\/\/github.com\/auth0\/node-jsonwebtoken\/\"><code>jsonwebtoken<\/code><\/a>;<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/jwks-rsa\"><code>jwks-rsa<\/code><\/a>: \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f <code>\u043a\u043b\u044e\u0447\u0435\u0439 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u0438\u044f\/signing keys<\/code> \u0438\u0437 <code>JWKS<\/code> (JSON Web Key Set\/\u043d\u0430\u0431\u043e\u0440 \u0432\u0435\u0431-\u043a\u043b\u044e\u0447\u0435\u0439 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>JSON<\/code>);<\/li>\n<li><a href=\"https:\/\/www.npmjs.com\/package\/nodemon\"><code>nodemon<\/code><\/a>: \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041e \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 <code>JWKS<\/code> \u0438 \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u043e\u043d \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/auth0.com\/docs\/security\/tokens\/json-web-tokens\/json-web-key-sets\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 <code>jwks-rsa<\/code> \u0441 <code>express-jwt<\/code> \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/auth0\/node-jwks-rsa\/tree\/61b5740b3846f74fa6d631be6712405700d9c163\/examples\/express-demo\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">- routes  - api.routes.js  - messages.routes.js - utils  - checkJwt.js - .env - index.js - ...<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u044e\u0442 2 \u0444\u0430\u0439\u043b\u0430: <code>messages.routes.js<\/code> \u0438 <code>checkJwt.js<\/code>.<\/p>\n<p>  <\/p>\n<p><code>messages.routes.js<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import { Router } from 'express' import { checkJwt } from '..\/utils\/checkJwt.js'  const router = Router()  router.get('\/public', (req, res) => {  res.status(200).json({ message: 'Public message' }) })  router.get('\/protected', checkJwt, (req, res) => {  res.status(200).json({ message: 'Protected message' }) })  export default router<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043a <code>api\/messages\/public<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 <code>Public message<\/code>. \u041f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043a <code>api\/messages\/protected<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 <code>JWT<\/code>. \u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 (\u0440\u043e\u0443\u0442) \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u044b\u043c. \u041a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u043e\u0448\u043b\u0430 \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 <code>Protected message<\/code>. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443.<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0430 (<code>utils\/checkJwt.js<\/code>).<\/p>\n<p>  <\/p>\n<p>\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0443\u0442\u0438\u043b\u0438\u0442\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">import jwt from 'express-jwt' import jwksRsa from 'jwks-rsa' import dotenv from 'dotenv'<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u0441\u0440\u0435\u0434\u044b \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u043c\u0441\u044f \u0432 \u0444\u0430\u0439\u043b\u0435 <code>.env<\/code>, \u0438 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">dotenv.config()  const domain = process.env.AUTH0_DOMAIN const audience = process.env.AUTH0_AUDIENCE<\/code><\/pre>\n<p>  <\/p>\n<p><code>audience<\/code> \u2014 \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u044d\u0442\u043e \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u0430, \u0442.\u0435. \u0442\u0435, \u0434\u043b\u044f \u043a\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0442\u043e\u043a\u0435\u043d.<\/p>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0443\u0442\u0438\u043b\u0438\u0442\u0443:<\/p>\n<p>  <\/p>\n<pre><code class=\"javascript\">export const checkJwt = jwt({  secret: jwksRsa.expressJwtSecret({    cache: true,    \/\/ \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432    rateLimit: true,    \/\/ 10 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432 \u043c\u0438\u043d\u0443\u0442\u0443    jwksRequestsPerMinute: 10,    \/\/ \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443 \u043f\u0443\u0442\u0438    jwksUri: `https:\/\/${domain}\/.well-known\/jwks.json`  }),  \/\/ \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044f  audience,  \/\/ \u0442\u043e\u0442, \u043a\u0442\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043b \u0442\u043e\u043a\u0435\u043d  issuer: `https:\/\/${domain}\/`,  \/\/ \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0434\u043b\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u0430  algorithms: ['RS256'] })<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0438\u043f \u043a\u043e\u0434\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u043c\u043e\u0434\u0443\u043b\u044c) \u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0432 <code>package.json<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"json\">\"type\": \"module\", \"scripts\": {  \"start\": \"node index.js\",  \"dev\": \"nodemon index.js\" }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>yarn dev<\/code> \u0438\u043b\u0438 <code>npm run dev<\/code> \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440.<\/p>\n<p>  <\/p>\n<p>\u0412\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 <code>MessagePage<\/code> \u0438 \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/gh\/lp\/oq\/ghlpoqtwx920dagspr0rosnkqqk.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/7w\/95\/tc\/7w95tcucx8yulctvu0xrnuh9sno.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<p>\u0410\u0432\u0442\u043e\u0440\u0438\u0437\u0443\u0435\u043c\u0441\u044f \u0438 \u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u043d\u043e\u0432\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/bi\/vt\/qz\/bivtqzqyhxthnii0f5vtchcgyhq.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c!<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0438\u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438\/\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043a\u0430\u043a \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u0421\u043e\u0433\u043b\u0430\u0441\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e <code>Auth0<\/code> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438\/\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0436\u0430\u043b\u0443\u0439, \u044d\u0442\u043e \u0432\u0441\u0435, \u0447\u0435\u043c \u044f \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0432\u044b \u043d\u0430\u0448\u043b\u0438 \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0447\u0442\u043e-\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u0438 \u043d\u0435 \u0437\u0440\u044f \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u043b\u0438 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<p>  <\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435. Happy coding \u0438 \u0441\u0447\u0430\u0441\u0442\u043b\u0438\u0432\u043e\u0433\u043e \u041d\u043e\u0432\u043e\u0433\u043e \u0433\u043e\u0434\u0430!<\/p>\n<p>  <\/p>\n<hr\/>\n<p>  <\/p>\n<p><a href=\"https:\/\/cloud.timeweb.com\/?utm_source=habr&amp;utm_medium=banner&amp;utm_campaign=cloud&amp;utm_content=direct&amp;utm_term=low\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/wn\/cq\/lp\/wncqlp9abeml4npwzsybuvhzcta.png\"\/><\/a><\/p>\n<\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/company\/timeweb\/blog\/598727\/\"> https:\/\/habr.com\/ru\/company\/timeweb\/blog\/598727\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\" class=\"article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" data-src=\"https:\/\/habrastorage.org\/webt\/pu\/no\/zh\/punozh3zkth3cqyppf_przd5wco.png\"\/>  <\/p>\n<p>  <\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0434\u0440\u0443\u0437\u044c\u044f!<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 (\u0434\u0430\u043b\u0435\u0435 \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0435\u0440\u0432\u0438\u0441) \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/auth0.com\/\"><code>Auth0<\/code><\/a>.<\/p>\n<p>  <\/p>\n<p><code>Auth0<\/code> \u2014 \u044d\u0442\u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0430\u044f \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u043b\u044e\u0431\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438. <code>Auth0<\/code> \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439, \u0441\u0442\u043e\u044f\u0449\u0435\u0439 \u0437\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 <a href=\"https:\/\/jwt.io\/\"><code>JWT<\/code><\/a> (JSON Web Token\/\u0432\u0435\u0431-\u0442\u043e\u043a\u0435\u043d \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>JSON<\/code>). \u042d\u0442\u043e \u0432\u0441\u0435\u043b\u044f\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 <code>Auth0-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0411\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f <code>Auth0<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e 7000 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<p>  <\/p>\n<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/company\/timeweb\/blog\/593063\/\">\u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u044f \u043f\u0438\u0441\u0430\u043b \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 <code>JWT<\/code>, \u0438 \u043a\u0430\u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0441 \u043d\u0443\u043b\u044f.<\/p>\n<p>  <\/p>\n<p>\u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 <code>Auth0<\/code> \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0447\u0430\u0442\u044c <a href=\"https:\/\/auth0.com\/docs\/get-started\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 <code>Auth0 SDK<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/auth0\/auth0-react\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c, \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f <a href=\"https:\/\/github.com\/harryheman\/Blog-Posts\/tree\/master\/react-auth0\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043e \u0441\u0430\u043c\u044b\u0445 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u0445, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 <code>Auth0<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445 \u0438 \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0430\u0445 \u043d\u0438\u0436\u0435 \u0432\u044b \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 <code>\u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435\/sensitive data<\/code>. \u042d\u0442\u043e \u043d\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041f\u043e\u0441\u043b\u0435 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-327150","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/327150","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=327150"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/327150\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=327150"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=327150"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=327150"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}