{"id":50669,"date":"2023-12-22T14:47:14","date_gmt":"2023-12-22T06:47:14","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/"},"modified":"2023-12-25T16:57:46","modified_gmt":"2023-12-25T08:57:46","slug":"%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/","title":{"rendered":"\u5982\u4f55\u901a\u8fc7\u4f7f\u7528HTTP-Only Cookies\u6765\u4fdd\u62a4React\u5e94\u7528\u514d\u53d7XSS\u653b\u51fb"},"content":{"rendered":"<h3>\u6982\u8ff0<\/h3>\n<p>\u57fa\u4e8e\u4ee4\u724c\u7684\u8eab\u4efd\u9a8c\u8bc1\u53ef\u4ee5\u4fdd\u62a4\u90a3\u4e9b\u5305\u542b\u516c\u5f00\u548c\u79c1\u6709\u8d44\u6e90\u7684\u7f51\u7edc\u5e94\u7528\u3002\u8bbf\u95ee\u79c1\u6709\u8d44\u6e90\u9700\u8981\u7528\u6237\u6210\u529f\u9a8c\u8bc1\u8eab\u4efd\uff0c\u901a\u5e38\u901a\u8fc7\u63d0\u4f9b\u4ec5\u7528\u6237\u81ea\u5df1\u77e5\u9053\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801\u3002\u9a8c\u8bc1\u6210\u529f\u540e\uff0c\u4f1a\u8fd4\u56de\u4e00\u4e2a\u4ee4\u724c\uff0c\u8be5\u4ee4\u724c\u7684\u6709\u6548\u671f\u7531\u7528\u6237\u51b3\u5b9a\uff0c\u8fd9\u6837\u7528\u6237\u5728\u8bbf\u95ee\u7279\u6743\u8d44\u6e90\u65f6\u53ef\u4ee5\u63d0\u4f9b\u8be5\u4ee4\u724c\u800c\u65e0\u9700\u91cd\u65b0\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u3002\u4ee4\u724c\u7684\u4f7f\u7528\u5f15\u53d1\u4e86\u4e00\u4e2a\u91cd\u8981\u95ee\u9898\uff0c\u5373\u5982\u4f55\u5b89\u5168\u5730\u5b58\u50a8\u4ee4\u724c\u3002\u53ef\u4ee5\u901a\u8fc7\u4f7f\u7528Window.localStorage\u6216Window.sessionStorage\u5c5e\u6027\u5c06\u4ee4\u724c\u5b58\u50a8\u5728\u6d4f\u89c8\u5668\u5b58\u50a8\u4e2d\uff0c\u4f46\u8fd9\u79cd\u65b9\u6cd5\u5bb9\u6613\u53d7\u5230\u8de8\u7ad9\u811a\u672c\uff08XSS\uff09\u653b\u51fb\u7684\u5f71\u54cd\uff0c\u56e0\u4e3a\u672c\u5730\u548c\u4f1a\u8bdd\u5b58\u50a8\u7684\u5185\u5bb9\u5bf9\u4e8e\u540c\u4e00\u6587\u6863\u4e0a\u8fd0\u884c\u7684JavaScript\u662f\u53ef\u8bbf\u95ee\u7684\u3002<\/p>\n<p>\u5728\u672c\u6559\u7a0b\u4e2d\uff0c\u60a8\u5c06\u521b\u5efa\u4e00\u4e2a React \u5e94\u7528\u7a0b\u5e8f\u548c\u6a21\u62df API\uff0c\u8be5\u5e94\u7528\u7a0b\u5e8f\u5b9e\u73b0\u4e86\u4e00\u4e2a\u57fa\u4e8e\u4ee4\u724c\u7684\u8eab\u4efd\u9a8c\u8bc1\u7cfb\u7edf\uff0c\u5e76\u5728\u672c\u5730 Docker \u5bb9\u5668\u4e2d\u8bbe\u7f6e\u4ee5\u4fbf\u5728\u5404\u4e2a\u5e73\u53f0\u4e0a\u8fdb\u884c\u4e00\u81f4\u7684\u6d4b\u8bd5\u3002\u60a8\u5c06\u9996\u5148\u4f7f\u7528\u6d4f\u89c8\u5668\u5b58\u50a8\u548c Window.localStorage \u5c5e\u6027\u5b9e\u73b0\u57fa\u4e8e\u4ee4\u724c\u7684\u8eab\u4efd\u9a8c\u8bc1\u3002\u7136\u540e\uff0c\u60a8\u5c06\u5229\u7528\u8fd9\u4e2a\u8bbe\u7f6e\u8fdb\u884c\u53cd\u5c04\u578b\u8de8\u7ad9\u811a\u672c\u653b\u51fb\uff0c\u4ee5\u4e86\u89e3\u5728\u4f7f\u7528\u6d4f\u89c8\u5668\u5b58\u50a8\u6765\u6301\u4e45\u4fdd\u5b58\u79d8\u5bc6\u4fe1\u606f\u65f6\u5b58\u5728\u7684\u5b89\u5168\u6f0f\u6d1e\u3002\u7136\u540e\uff0c\u60a8\u5c06\u901a\u8fc7\u5c06\u5e94\u7528\u7a0b\u5e8f\u66f4\u6539\u4e3a\u4f7f\u7528 HTTP-only cookies \u5b58\u50a8\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u6765\u6539\u8fdb\u6b64\u5e94\u7528\u7a0b\u5e8f\uff0c\u8fd9\u5c06\u4e0d\u518d\u88ab\u6f5c\u5728\u6076\u610f\u7684 JavaScript \u4ee3\u7801\u8bbf\u95ee\uff0c\u8be5\u4ee3\u7801\u53ef\u80fd\u5b58\u5728\u4e8e\u6587\u6863\u4e2d\u3002<\/p>\n<p>\u901a\u8fc7\u672c\u6559\u7a0b\u7684\u6700\u540e\uff0c\u60a8\u5c06\u7406\u89e3\u5728React\u548cNode Web\u5e94\u7528\u7a0b\u5e8f\u4e2d\u5b9e\u73b0\u529f\u80fd\u5f3a\u5927\u7684\u57fa\u4e8e\u4ee4\u724c\u7684\u8eab\u4efd\u9a8c\u8bc1\u7cfb\u7edf\u6240\u9700\u7684\u5b89\u5168\u8003\u8651\u3002\u672c\u6559\u7a0b\u7684\u4ee3\u7801\u53ef\u5728DigitalOcean\u793e\u533a\u7684GitHub\u4e0a\u83b7\u53d6\u3002<\/p>\n<h2>\u5148\u51b3\u6761\u4ef6<\/h2>\n<p>\u5b8c\u6210\u8fd9\u4e2a\u6559\u7a0b\uff0c\u4f60\u9700\u8981\u4ee5\u4e0b\u5de5\u5177\/\u6750\u6599\uff1a<\/p>\n<ul class=\"post-ul\">\n<li>A local development environment inside of a Docker container, which you will prepare in Step 1. You can install Docker directly or follow the tutorial on How to Install and Use Docker on Ubuntu 22.04.\n<p>The application in this tutorial was built on an image running node:18.7.0-bullseye. You can also install Node.js with the How to Install Node.js and Create a Local Development Environment series.<\/p>\n<\/li>\n<li>A browser to test and develop the application. This tutorial uses the Firefox browser. Using a different browser can have unexpected results.<\/li>\n<li>Familiarity working with React is helpful. You can reference How To Call Web APIs with the useEffect Hook in React as needed for fetching data from APIs. You can also refer to How To Add Login Authentication to React Applications for help with rudimentary authentication systems.<\/li>\n<li>You will be creating and manipulating HTTP-only cookies. For more on cookies, refer to What Are Cookies &#038; How to Work With Them Using JavaScript and How To Use JSON Web Tokens (JWTs) in Express.js.<\/li>\n<li>Knowledge of JavaScript, HTML, and CSS. Refer to How To Build a Website With HTML series, How To Style HTML with CSS, and in How To Code in JavaScript.<\/li>\n<\/ul>\n<h2>\u6b65\u9aa4\u4e00 \u2014 \u4e3a\u5f00\u53d1\u51c6\u5907\u4e00\u4e2a Docker \u5bb9\u5668<\/h2>\n<p>\u5728\u8fd9\u4e00\u6b65\u4e2d\uff0c\u60a8\u5c06\u4e3a\u5f00\u53d1\u76ee\u7684\u8bbe\u7f6e\u4e00\u4e2aDocker\u5bb9\u5668\u3002\u9996\u5148\uff0c\u60a8\u5c06\u521b\u5efa\u4e00\u4e2aDockerfile\uff0c\u5e76\u63d0\u4f9b\u6784\u5efa\u955c\u50cf\u4ee5\u521b\u5efa\u5bb9\u5668\u7684\u6307\u4ee4\u3002<\/p>\n<p>\u4f7f\u7528nano\u6216\u8005\u4f60\u559c\u6b22\u7684\u7f16\u8f91\u5668\uff0c\u5728\u4f60\u7684\u4e3b\u76ee\u5f55\u4e2d\u521b\u5efa\u5e76\u6253\u5f00\u4e00\u4e2a\u540d\u4e3aDockerfile\u7684\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> Dockerfile\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5c06\u4ee5\u4e0b\u4ee3\u7801\u884c\u653e\u7f6e\u5728\u5176\u4e2d\uff1a<\/p>\n<div>Dockerfile\u53ef\u4ee5\u88ab\u4e2d\u56fd\u4eba\u50cf\u6bcd\u8bed\u4e00\u6837\u5730\u89e3\u91ca\u4e3a\uff1a\u955c\u50cf\u6587\u4ef6\u3002<\/div>\n<pre class=\"post-pre\"><code><span class=\"token instruction\"><span class=\"token keyword\">FROM<\/span> node:18.7.0-bullseye<\/span>\r\n\r\n<span class=\"token instruction\"><span class=\"token keyword\">RUN<\/span> apt update -y <span class=\"token operator\">\\<\/span>\r\n    &amp;&amp; apt upgrade -y <span class=\"token operator\">\\<\/span>\r\n    &amp;&amp; apt install -y vim nano <span class=\"token operator\">\\<\/span>\r\n    &amp;&amp; mkdir \/app<\/span>\r\n\r\n<span class=\"token instruction\"><span class=\"token keyword\">WORKDIR<\/span> \/app<\/span>\r\n\r\n<span class=\"token instruction\"><span class=\"token keyword\">CMD<\/span> [ <span class=\"token string\">\"tail\"<\/span>, <span class=\"token string\">\"-f\"<\/span>, <span class=\"token string\">\"\/dev\/null\"<\/span> ]<\/span>\r\n<\/code><\/pre>\n<p>FROM\u884c\u4f7f\u7528\u9884\u5148\u6784\u5efa\u7684node:18.7.0-bullseye\u4f5c\u4e3a\u57fa\u7840\u955c\u50cf\u521b\u5efa\u60a8\u7684\u56fe\u50cf\u3002\u8be5\u955c\u50cf\u5df2\u7ecf\u5b89\u88c5\u4e86\u5fc5\u8981\u7684NodeJS\u4f9d\u8d56\u9879\uff0c\u5c06\u7b80\u5316\u60a8\u7684\u8bbe\u7f6e\u8fc7\u7a0b\u3002<\/p>\n<p>RUN \u547d\u4ee4\u7528\u4e8e\u66f4\u65b0\u548c\u5347\u7ea7\u8f6f\u4ef6\u5305\uff0c\u540c\u65f6\u4e5f\u53ef\u4ee5\u5b89\u88c5\u5176\u4ed6\u4f60\u53ef\u80fd\u9700\u8981\u7684\u8f6f\u4ef6\u5305\u3002WORKDIR \u547d\u4ee4\u8bbe\u7f6e\u5de5\u4f5c\u76ee\u5f55\u3002<\/p>\n<p>CMD\u884c\u5b9a\u4e49\u5728\u5bb9\u5668\u5185\u8fd0\u884c\u7684\u4e3b\u8981\u8fdb\u7a0b\uff0c\u786e\u4fdd\u5bb9\u5668\u4fdd\u6301\u8fd0\u884c\u72b6\u6001\uff0c\u4ee5\u4fbf\u60a8\u53ef\u4ee5\u8fde\u63a5\u5e76\u7528\u4e8e\u5f00\u53d1\u3002<\/p>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u4f7f\u7528docker build\u547d\u4ee4\u521b\u5efaDocker\u955c\u50cf\uff0c\u5c06&#8221;path_to_your_dockerfile&#8221;\u66ff\u6362\u4e3a\u60a8\u7684Dockerfile\u8def\u5f84\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">docker<\/span> build <span class=\"token parameter variable\">-f<\/span> \/<mark>path_to_your_dockerfile<\/mark> <span class=\"token parameter variable\">--tag<\/span> jwt-tutorial-image <span class=\"token builtin class-name\">.<\/span>\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u60a8\u5c06\u4f7f\u7528-f\u9009\u9879\u5c06Dockerfile\u7684\u8def\u5f84\u4f20\u9012\u7ed9\u6307\u793a\u8981\u6784\u5efa\u56fe\u50cf\u7684\u6587\u4ef6\u8def\u5f84\u3002\u60a8\u53ef\u4ee5\u4f7f\u7528&#8211;tag\u9009\u9879\u4e3a\u6b64\u6784\u5efa\u6dfb\u52a0\u6807\u7b7e\uff0c\u4ece\u800c\u53ef\u4ee5\u540e\u7eed\u4f7f\u7528\u6613\u4e8e\u7406\u89e3\u7684\u540d\u79f0\uff08\u5728\u672c\u4f8b\u4e2d\u4e3ajwt-tutorial-image\uff09\u6765\u5f15\u7528\u5b83\u3002<\/p>\n<p>\u8fd0\u884c\u6784\u5efa\u547d\u4ee4\u540e\uff0c\u60a8\u5c06\u770b\u5230\u7c7b\u4f3c\u4e8e\u4ee5\u4e0b\u8f93\u51fa\u7684\u7ed3\u679c\uff1a<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>...\r\n =&gt; =&gt; writing image sha256:1cf8f3253e430cba962a1d205d5c919eb61ad106e2933e33644e0bc4e2cdc433                                    0.0s \r\n =&gt; =&gt; naming to docker.io\/library\/jwt-tutorial-image   \r\n<\/code><\/pre>\n<p>\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u5c06\u56fe\u50cf\u4f5c\u4e3a\u5bb9\u5668\u8fd0\u884c\uff1a<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">docker<\/span> run <span class=\"token parameter variable\">-d<\/span> <span class=\"token parameter variable\">-p<\/span> <span class=\"token number\">3000<\/span>:3000 <span class=\"token parameter variable\">-p<\/span> <span class=\"token number\">8080<\/span>:8080 <span class=\"token parameter variable\">--name<\/span> jwt-tutorial-container jwt-tutorial-image\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>-d\u9009\u9879\u4ee5\u5206\u79bb\u6a21\u5f0f\u8fd0\u884c\u5bb9\u5668\uff0c\u8fd9\u6837\u60a8\u53ef\u4ee5\u4f7f\u7528\u5355\u72ec\u7684\u7ec8\u7aef\u4f1a\u8bdd\u8fde\u63a5\u5230\u5b83\u3002<\/p>\n<div class=\"post-conf-note\">\n<p class=\"post-note\">\n<p class=\"post-conf-desc\">Note<\/p>\n<div>\u6ce8\u610f\uff1a\u5982\u679c\u4f60\u5b81\u613f\u4f7f\u7528\u6b63\u5728\u8fd0\u884cDocker\u5bb9\u5668\u7684\u540c\u4e00\u7ec8\u7aef\u8fdb\u884c\u5f00\u53d1\uff0c\u8bf7\u5c06&#8221;-d&#8221;\u6807\u5fd7\u66ff\u6362\u4e3a&#8221;-it&#8221;\uff0c\u8fd9\u6837\u4f1a\u7acb\u5373\u4e3a\u4f60\u63d0\u4f9b\u4e00\u4e2a\u5728\u5bb9\u5668\u5185\u90e8\u8fd0\u884c\u7684\u4ea4\u4e92\u5f0f\u7ec8\u7aef\u3002<\/div>\n<\/div>\n<p>-p \u6807\u5fd7\u5c06\u8f6c\u53d1\u5bb9\u5668\u7684\u7aef\u53e33000\u548c8080\u3002\u8fd9\u4e9b\u7aef\u53e3\u5206\u522b\u4e3a\u60a8\u7684\u4e3b\u673a\u7684localhost\u7f51\u7edc\u63d0\u4f9b\u524d\u7aef\u548c\u540e\u7aef\u5e94\u7528\u7a0b\u5e8f\uff0c\u4ee5\u4fbf\u60a8\u53ef\u4ee5\u4f7f\u7528\u672c\u5730\u6d4f\u89c8\u5668\u6d4b\u8bd5\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<div class=\"post-conf-note\">\n<p class=\"post-note\">\n<p class=\"post-conf-desc\">Note<\/p>\n<div>\u6ce8\u610f\uff1a\u5982\u679c\u60a8\u7684\u4e3b\u673a\u5f53\u524d\u6b63\u5728\u4f7f\u75283000\u548c8080\u7aef\u53e3\uff0c\u60a8\u9700\u8981\u505c\u6b62\u4f7f\u7528\u8fd9\u4e9b\u7aef\u53e3\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u5426\u5219\u5728\u5c1d\u8bd5\u8f6c\u53d1\u7aef\u53e3\u65f6\uff0cDocker\u4f1a\u629b\u51fa\u4e00\u4e2a\u9519\u8bef\u3002<br \/>\n\u60a8\u8fd8\u53ef\u4ee5\u4f7f\u7528-P\u6807\u5fd7\u5c06\u5bb9\u5668\u7684\u7aef\u53e3\u8f6c\u53d1\u5230\u4e3b\u673a\u7684\u672a\u4f7f\u7528\u7aef\u53e3\u4e0a\u3002\u5982\u679c\u60a8\u4f7f\u7528-P\u6807\u5fd7\u800c\u4e0d\u662f\u6620\u5c04\u7279\u5b9a\u7684\u7aef\u53e3\uff0c\u60a8\u9700\u8981\u8fd0\u884cdocker network inspect\u547d\u4ee4\uff0c\u4ee5\u4e86\u89e3\u54ea\u4e9b\u5f00\u53d1\u5bb9\u5668\u7aef\u53e3\u6620\u5c04\u5230\u4e86\u54ea\u4e9b\u672c\u5730\u7aef\u53e3\u3002<\/div>\n<\/div>\n<p>\u4f60\u8fd8\u53ef\u4ee5\u4f7f\u7528Remote Containers\u63d2\u4ef6\u4e0eVSCode\u8fdb\u884c\u8fde\u63a5\u3002<\/p>\n<p>\u5728\u4e00\u4e2a\u5355\u72ec\u7684\u7ec8\u7aef\u4f1a\u8bdd\u4e2d\uff0c\u8fd0\u884c\u8fd9\u4e2a\u547d\u4ee4\u6765\u8fde\u63a5\u5230\u5bb9\u5668\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">docker<\/span> <span class=\"token builtin class-name\">exec<\/span> <span class=\"token parameter variable\">-it<\/span> jwt-tutorial-container \/bin\/bash\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u901a\u8fc7\u4f60\u7684\u5bb9\u5668\u6807\u7b7e\uff0c\u4f60\u4f1a\u770b\u5230\u7c7b\u4f3c\u8fd9\u6837\u7684\u8fde\u63a5\uff0c\u8868\u660e\u4f60\u5df2\u7ecf\u8fde\u63a5\u6210\u529f\u3002<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>root@<mark>d7e051c96368<\/mark>:\/app# \r\n<\/code><\/pre>\n<p>\u5728\u8fd9\u4e00\u6b65\u4e2d\uff0c\u60a8\u5c06\u8bbe\u7f6e\u4e00\u4e2a\u9884\u6784\u5efa\u7684Docker\u955c\u50cf\uff0c\u5e76\u8fde\u63a5\u5230\u60a8\u5c06\u7528\u4e8e\u5f00\u53d1\u7684\u5bb9\u5668\u3002\u63a5\u4e0b\u6765\uff0c\u60a8\u5c06\u4f7f\u7528create-react-app\u5728\u5bb9\u5668\u4e2d\u8bbe\u7f6e\u5e94\u7528\u7a0b\u5e8f\u7684\u6846\u67b6\u3002<\/p>\n<h2>\u7b2c\u4e8c\u6b65 &#8211; \u5efa\u7acb\u524d\u7aef\u5e94\u7528\u7684\u57fa\u7840\u7ed3\u6784<\/h2>\n<p>\u5728\u8fd9\u4e2a\u6b65\u9aa4\u4e2d\uff0c\u60a8\u5c06\u521d\u59cb\u5316\u60a8\u7684React\u5e94\u7528\u7a0b\u5e8f\uff0c\u5e76\u4f7f\u7528\u4e00\u4e2aecosystem.config.js\u6587\u4ef6\u914d\u7f6e\u5e94\u7528\u7a0b\u5e8f\u7ba1\u7406\u3002<\/p>\n<p>\u8fde\u63a5\u5230\u5bb9\u5668\u540e\uff0c\u4f7f\u7528mkdir\u547d\u4ee4\u4e3a\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u521b\u5efa\u4e00\u4e2a\u76ee\u5f55\uff0c\u7136\u540e\u4f7f\u7528cd\u547d\u4ee4\u8fdb\u5165\u65b0\u521b\u5efa\u7684\u76ee\u5f55\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">mkdir<\/span> \/app\/jwt-storage-tutorial\r\n<\/li><li data-prefix=\"$\"><span class=\"token builtin class-name\">cd<\/span> \/app\/jwt-storage-tutorial\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u7136\u540e\u4f7f\u7528npx\u547d\u4ee4\u8fd0\u884ccreate-react-app\u4e8c\u8fdb\u5236\u6587\u4ef6\uff0c\u521d\u59cb\u5316\u4e00\u4e2a\u65b0\u7684React\u9879\u76ee\uff0c\u4f5c\u4e3a\u60a8\u7684\u7f51\u9875\u5e94\u7528\u7684\u524d\u7aef\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\">npx create-react-app front-end\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>create-react-app\u4e8c\u8fdb\u5236\u6587\u4ef6\u53ef\u4ee5\u521d\u59cb\u5316\u4e00\u4e2a\u7b80\u5355\u7684React\u5e94\u7528\u7a0b\u5e8f\uff0c\u5176\u4e2d\u5305\u542b\u4e00\u4e2a\u7528\u4e8e\u5f00\u53d1\u548c\u6d4b\u8bd5\u5e94\u7528\u7a0b\u5e8f\u7684README\u6587\u4ef6\uff0c\u4ee5\u53ca\u5305\u62ecreact-scripts\u3001react-dom\u548cjest\u5728\u5185\u7684\u51e0\u4e2a\u5e7f\u6cdb\u4f7f\u7528\u7684\u4f9d\u8d56\u9879\u3002<\/p>\n<p>\u5728\u63d0\u793a\u65f6\u8f93\u5165\u201cy\u201d\u4ee5\u7ee7\u7eed\u5b89\u88c5\u3002<\/p>\n<p>\u4f60\u5c06\u4f1a\u770b\u5230\u4f7f\u7528create-react-app\u547d\u4ee4\u521b\u5efa\u7684\u8fd9\u4e2a\u8f93\u51fa\u3002<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>...\r\n\r\nSuccess! Created front-end at \/home\/nodejs\/jwt-storage-tutorial\/front-end\r\nInside that directory, you can run several commands:\r\n\r\n  yarn start\r\n    Starts the development server.\r\n\r\n  yarn build\r\n    Bundles the app into static files for production.\r\n\r\n  yarn test\r\n    Starts the test runner.\r\n\r\n  yarn eject\r\n    Removes this tool and copies build dependencies, configuration files\r\n    and scripts into the app directory. If you do this, you can\u2019t go back!\r\n\r\nWe suggest that you begin by typing:\r\n\r\n  cd front-end\r\n  yarn start\r\n\r\nHappy hacking!\r\n<\/code><\/pre>\n<p>\u4f7f\u7528\u4e0d\u540c\u7248\u672c\u7684create-react-app\uff0c\u4f60\u7684\u8f93\u51fa\u53ef\u80fd\u4f1a\u7565\u6709\u4e0d\u540c\u3002<\/p>\n<p>\u4f60\u5df2\u7ecf\u51c6\u5907\u597d\u542f\u52a8\u4e00\u4e2a\u5f00\u53d1\u5b9e\u4f8b\u5e76\u5f00\u59cb\u8fdb\u884c\u65b0\u7684React\u5e94\u7528\u7a0b\u5e8f\u7684\u5de5\u4f5c\u3002<\/p>\n<p>\u8981\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\uff0c\u60a8\u5c06\u4f7f\u7528PM2\u8fdb\u7a0b\u7ba1\u7406\u5668\u3002\u4f7f\u7528\u4ee5\u4e0b\u547d\u4ee4\u5b89\u88c5pm2\uff1a<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">npm<\/span> <span class=\"token function\">install<\/span> pm2 <span class=\"token parameter variable\">-g<\/span>\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u4f7f\u7528-g\u6807\u5fd7\u53ef\u4ee5\u5168\u5c40\u5b89\u88c5\u8f6f\u4ef6\u5305\u3002\u6839\u636e\u4f60\u6240\u767b\u5f55\u7528\u6237\u7684\u6743\u9650\uff0c\u4f60\u53ef\u80fd\u9700\u8981\u4f7f\u7528sudo\u547d\u4ee4\u6765\u5168\u5c40\u5b89\u88c5\u8f6f\u4ef6\u5305\u3002<\/p>\n<p>PM2\u5728\u5e94\u7528\u7684\u5f00\u53d1\u548c\u751f\u4ea7\u9636\u6bb5\u63d0\u4f9b\u4e86\u51e0\u4e2a\u4f18\u52bf\u3002\u4f8b\u5982\uff0c\u5728\u5f00\u53d1\u671f\u95f4\u4f7f\u7528PM2\u53ef\u4ee5\u5c06\u5e94\u7528\u7684\u4e0d\u540c\u7ec4\u4ef6\u4fdd\u6301\u5728\u540e\u53f0\u8fd0\u884c\u3002\u5728\u751f\u4ea7\u4e2d\uff0c\u60a8\u8fd8\u53ef\u4ee5\u4f7f\u7528PM2\u6765\u6ee1\u8db3\u8fd0\u8425\u9700\u6c42\uff0c\u4f8b\u5982\u901a\u8fc7\u5b9e\u65bd\u90e8\u7f72\u6a21\u578b\uff0c\u4ee5\u6700\u5c0f\u7684\u505c\u673a\u65f6\u95f4\u5bf9\u751f\u4ea7\u5e94\u7528\u8fdb\u884c\u4fee\u8865\u3002\u60f3\u8981\u4e86\u89e3\u66f4\u591a\u4fe1\u606f\uff0c\u60a8\u53ef\u4ee5\u9605\u8bfb\u300aPM2\uff1a\u5206\u949f\u7ea7\u751f\u4ea7\u5c31\u7eea\u7684Node.js\u5e94\u7528\u300b\u3002<\/p>\n<p>\u5b89\u88c5\u7684\u7ed3\u679c\u5c06\u7c7b\u4f3c\u4e8e\u4ee5\u4e0b\u5185\u5bb9\uff1a<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>added 183 packages, and audited 184 packages in 2m\r\n12 packages are looking for funding\r\n  run `npm fund` for details\r\nfound 0 vulnerabilities --&gt;\r\n<\/code><\/pre>\n<p>\u8981\u4f7f\u7528PM2\u8fdb\u7a0b\u7ba1\u7406\u5668\u6765\u8fd0\u884c\u5e94\u7528\u7a0b\u5e8f\uff0c\u8fdb\u5165\u60a8\u7684React\u9879\u76ee\u76ee\u5f55\uff0c\u7136\u540e\u4f7f\u7528nano\u6216\u60a8\u559c\u6b22\u7684\u7f16\u8f91\u5668\u521b\u5efa\u4e00\u4e2a\u540d\u4e3aecosystem.config.js\u7684\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token builtin class-name\">cd<\/span> front-end\r\n<\/li><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> ecosystem.config.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>ecosystem.config.js\u6587\u4ef6\u5c06\u4fdd\u5b58PM2\u8fdb\u7a0b\u7ba1\u7406\u5668\u5bf9\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u8fd0\u884c\u65b9\u5f0f\u7684\u914d\u7f6e\u3002<\/p>\n<p>\u5c06\u4ee5\u4e0b\u4ee3\u7801\u6dfb\u52a0\u5230\u65b0\u521b\u5efa\u7684 ecosystem.config.js \u6587\u4ef6\u4e2d\u3002<\/p>\n<div>jwt-storage-tutorial\u524d\u7aefecosystem.config.js<\/div>\n<pre class=\"post-pre\"><code>module<span class=\"token punctuation\">.<\/span>exports <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token literal-property property\">apps<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span>\r\n    <span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">name<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'front-end'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">cwd<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'\/app\/jwt-storage-tutorial\/front-end'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">script<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'npm'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">args<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'run start'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">env<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span>\r\n        <span class=\"token constant\">PORT<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">3000<\/span>\r\n      <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>\r\n  <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span>\r\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u5728\u8fd9\u91cc\uff0c\u60a8\u4f7f\u7528PM2\u8fdb\u7a0b\u7ba1\u7406\u5668\u5b9a\u4e49\u4e00\u4e2a\u65b0\u7684\u5e94\u7528\u7a0b\u5e8f\u914d\u7f6e\u3002name\u914d\u7f6e\u53c2\u6570\u5141\u8bb8\u60a8\u4e3a\u60a8\u7684\u8fdb\u7a0b\u5728PM2\u8fdb\u7a0b\u8868\u4e2d\u9009\u62e9\u4e00\u4e2a\u540d\u79f0\uff0c\u4ee5\u4fbf\u4e8e\u8bc6\u522b\u3002cwd\u53c2\u6570\u8bbe\u7f6e\u60a8\u5c06\u8981\u8fd0\u884c\u7684\u9879\u76ee\u7684\u6839\u76ee\u5f55\u3002script\u548cargs\u53c2\u6570\u5141\u8bb8\u60a8\u9009\u62e9\u7528\u4e8e\u8fd0\u884c\u7a0b\u5e8f\u7684\u547d\u4ee4\u884c\u5de5\u5177\u3002\u6700\u540e\uff0cenv\u53c2\u6570\u5141\u8bb8\u60a8\u4f20\u5165\u4e00\u4e2aJSON\u5bf9\u8c61\uff0c\u4ee5\u4fbf\u4e3a\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u8bbe\u7f6e\u5fc5\u8981\u7684\u73af\u5883\u53d8\u91cf\u3002\u60a8\u53ea\u5b9a\u4e49\u4e86\u4e00\u4e2a\u73af\u5883\u53d8\u91cfPORT\uff0c\u5b83\u8bbe\u7f6e\u4e86\u524d\u7aef\u5e94\u7528\u7a0b\u5e8f\u5c06\u8981\u8fd0\u884c\u7684\u7aef\u53e3\u3002<\/p>\n<p>\u4fdd\u5b58\u5e76\u9000\u51fa\u6587\u4ef6\u3002<\/p>\n<p>\u8bf7\u4f7f\u7528\u8be5\u547d\u4ee4\u68c0\u67e5PM2\u7ba1\u7406\u5668\u5f53\u524d\u8fd0\u884c\u7684\u8fdb\u7a0b\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\">pm2 list\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u60a8\u76ee\u524d\u6ca1\u6709\u5728PM2\u4e0a\u8fd0\u884c\u4efb\u4f55\u8fdb\u7a0b\uff0c\u6240\u4ee5\u60a8\u4f1a\u5f97\u5230\u8fd9\u4e2a\u8f93\u51fa\u3002<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>\u250c\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\r\n\u2502 id \u2502 name               \u2502 mode     \u2502 \u21ba    \u2502 status    \u2502 cpu      \u2502 memory   \u2502\r\n\u2514\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\r\n<\/code><\/pre>\n<p>\u5982\u679c\u60a8\u6b63\u5728\u8fd0\u884c\u547d\u4ee4\u5e76\u9700\u8981\u91cd\u7f6e\u8fdb\u7a0b\u7ba1\u7406\u5668\u4ee5\u6e05\u9664\u65e7\u6570\u636e\uff0c\u8bf7\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\uff1a<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\">pm2 delete all\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u73b0\u5728\uff0c\u4f7f\u7528\u5728\u4f60\u7684ecosystem.config.js\u6587\u4ef6\u4e2d\u6307\u5b9a\u7684\u914d\u7f6e\uff0c\u4f7f\u7528PM2\u8fdb\u7a0b\u7ba1\u7406\u5668\u542f\u52a8\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\">pm2 start ecosystem.config.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u4f60\u4f1a\u5728\u7ec8\u7aef\u4e0a\u770b\u5230\u7c7b\u4f3c\u8fd9\u6837\u7684\u8f93\u51fa\u3002<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>\u250c\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\r\n\u2502 id \u2502 name               \u2502 mode     \u2502 \u21ba    \u2502 status    \u2502 cpu      \u2502 memory   \u2502\r\n\u251c\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\r\n\u2502 0  \u2502 front-end          \u2502 fork     \u2502 0    \u2502 online    \u2502 0%       \u2502 33.6mb   \u2502\r\n\u2514\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\r\n<\/code><\/pre>\n<p>\u60a8\u53ef\u4ee5\u4f7f\u7528\u505c\u6b62\uff08stop\uff09\u548c\u542f\u52a8\uff08start\uff09\u547d\u4ee4\u4ee5\u53ca\u91cd\u65b0\u542f\u52a8\uff08restart\uff09\u548c\u542f\u52a8\u6216\u91cd\u65b0\u542f\u52a8\uff08startOrRestart\uff09\u547d\u4ee4\u6765\u63a7\u5236PM2\u8fdb\u7a0b\u7684\u6d3b\u52a8\u3002<\/p>\n<p>\u60a8\u53ef\u4ee5\u901a\u8fc7\u5728\u60a8\u504f\u597d\u7684\u6d4f\u89c8\u5668\u4e2d\u5bfc\u822a\u81f3http:\/\/localhost:3000\u6765\u67e5\u770b\u5e94\u7528\u7a0b\u5e8f\u3002\u5c06\u663e\u793a\u9ed8\u8ba4\u7684React\u6b22\u8fce\u9875\u9762\u3002<\/p>\n<div>\n                            <img decoding=\"async\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/6564666ea4b2f92e6c7266b0\/74-0.png\" class='post-images' alt=\"Screencapture of the React application's initial startup display in the browser\" title=\"\">\n                        <\/div>\n<p>\u6700\u540e\uff0c\u5728\u5ba2\u6237\u7aef\u8def\u7531\u4e2d\u5b89\u88c5React-Router\u76845.2.0\u7248\u672c\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">npm<\/span> <span class=\"token function\">install<\/span> react-router-dom@5.2.0\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5f53\u5b89\u88c5\u5b8c\u6210\u65f6\uff0c\u60a8\u5c06\u6536\u5230\u4ee5\u4e0b\u53d8\u4f53\u7684\u6d88\u606f\uff1a<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>...\r\n\r\nadded 13 packages, and audited 1460 packages in 7s\r\n\r\n205 packages are looking for funding\r\n  run `npm fund` for details\r\n\r\n6 high severity vulnerabilities\r\n\r\nTo address all issues (including breaking changes), run:\r\n  npm audit fix --force\r\n\r\nRun `npm audit` for details.\r\n<\/code><\/pre>\n<p>\u5728\u8fd9\u4e00\u6b65\u4e2d\uff0c\u60a8\u5728Docker\u5bb9\u5668\u4e2d\u8bbe\u7f6eReact\u5e94\u7528\u7a0b\u5e8f\u7684\u9aa8\u67b6\u3002\u63a5\u4e0b\u6765\uff0c\u60a8\u5c06\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u7684\u9875\u9762\uff0c\u7a0d\u540e\u5c06\u7528\u4e8e\u5bf9\u6297XSS\u653b\u51fb\u8fdb\u884c\u6d4b\u8bd5\u3002<\/p>\n<h2>\u7b2c\u4e09\u6b65 &#8211; \u6784\u5efa\u767b\u5f55\u9875\u9762<\/h2>\n<p>\u5728\u8fd9\u4e00\u6b65\u4e2d\uff0c\u60a8\u5c06\u4e3a\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u521b\u5efa\u4e00\u4e2a\u767b\u5f55\u9875\u9762\u3002\u60a8\u5c06\u4f7f\u7528\u7ec4\u4ef6\u6765\u8868\u793a\u4e00\u4e2a\u65e2\u6709\u79c1\u6709\u8d44\u4ea7\u53c8\u6709\u516c\u5171\u8d44\u4ea7\u7684\u5e94\u7528\u7a0b\u5e8f\u3002\u63a5\u4e0b\u6765\uff0c\u60a8\u5c06\u5b9e\u73b0\u4e00\u4e2a\u767b\u5f55\u9875\u9762\uff0c\u5728\u8be5\u9875\u9762\u4e0a\u7528\u6237\u5c06\u9a8c\u8bc1\u81ea\u5df1\u4ee5\u83b7\u5f97\u8bbf\u95ee\u7f51\u7ad9\u79c1\u6709\u8d44\u4ea7\u7684\u6743\u9650\u3002\u5230\u672c\u6b65\u9aa4\u7ed3\u675f\u65f6\uff0c\u60a8\u5c06\u62e5\u6709\u4e00\u4e2a\u6807\u51c6\u5e94\u7528\u7a0b\u5e8f\u7684\u6846\u67b6\uff0c\u5305\u542b\u79c1\u6709\u548c\u516c\u5171\u8d44\u4ea7\u4ee5\u53ca\u4e00\u4e2a\u767b\u5f55\u9875\u9762\u3002<\/p>\n<p>\u9996\u5148\uff0c\u4f60\u5c06\u521b\u5efa\u4e3b\u9875\u548c\u767b\u5f55\u9875\u9762\u3002\u7136\u540e\uff0c\u4f60\u5c06\u521b\u5efa\u4e00\u4e2aSubscriberFeed\u7ec4\u4ef6\uff0c\u7528\u4e8e\u8868\u793a\u53ea\u6709\u767b\u5f55\u7528\u6237\u624d\u80fd\u67e5\u770b\u7684\u79c1\u5bc6\u9875\u9762\u3002<\/p>\n<p>\u9996\u5148\uff0c\u521b\u5efa\u4e00\u4e2a\u7ec4\u4ef6\u76ee\u5f55\u6765\u5b58\u653e\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u6240\u6709\u7ec4\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">mkdir<\/span> src\/components\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u7136\u540e\uff0c\u5728\u7ec4\u4ef6\u76ee\u5f55\u4e2d\u521b\u5efa\u5e76\u6253\u5f00\u4e00\u4e2a\u540d\u4e3aSubscriberFeed.js\u7684\u65b0\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> src\/components\/SubscriberFeed.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5728SubscriberFeed.js\u6587\u4ef6\u5185\u90e8\uff0c\u4f7f\u7528\u4e00\u4e2a&lt;h2&gt;\u6807\u7b7e\uff0c\u5e76\u6dfb\u52a0\u4ee5\u4e0b\u884c\u4ee3\u7801\uff0c\u5176\u4e2d\u5305\u542b\u7ec4\u4ef6\u6807\u9898\u3002<\/h2>\n<\/p>\n<div>\u8bf7\u5c06\u4ee5\u4e0b\u5185\u5bb9\u4ee5\u4e2d\u6587\u8fdb\u884c\u91cd\u8ff0\uff0c\u53ea\u9700\u63d0\u4f9b\u4e00\u79cd\u9009\u9879\uff1a<br \/>\njwt-storage-tutorial\/front-end\/src\/components\/SubscriberFeed.js<\/p>\n<p>JWT\u5b58\u50a8\u6559\u7a0b\u524d\u7aef\u4ee3\u7801\u4e2d\uff0c\u4f4d\u4e8e\/components\/SubscriberFeed.js\u6587\u4ef6\u4e2d\u3002<\/p><\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> React <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>h2<span class=\"token operator\">&gt;<\/span>Subscriber Feed<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h2<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n<\/code><\/pre>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u60a8\u5c06\u5728App.js\u6587\u4ef6\u4e2d\u5bfc\u5165SubscriberFeed\u7ec4\u4ef6\uff0c\u5e76\u521b\u5efa\u8def\u7531\u4ee5\u4f7f\u8be5\u7ec4\u4ef6\u5bf9\u7528\u6237\u53ef\u8bbf\u95ee\u3002\u6253\u5f00\u60a8\u9879\u76ee\u4e2dsrc\u76ee\u5f55\u4e0b\u7684App.js\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> src\/App.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5c06\u4e0b\u9762\u6807\u8bb0\u7684\u4ee3\u7801\u884c\u6dfb\u52a0\u5230\u5bfc\u5165\u8bed\u53e5\u4e2d\uff0c\u4ecereact-router-dom\u5305\u4e2d\u5bfc\u5165BrowserRouter\u3001Switch\u548cRoute\u7ec4\u4ef6\u3002<\/p>\n<div>jwt-storage-tutorial\/front-end\/src\/App.js \u7684\u5185\u5bb9\u5982\u4e0b<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<mark><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> BrowserRouter<span class=\"token punctuation\">,<\/span> Route<span class=\"token punctuation\">,<\/span> Switch <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>header className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>img src<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>logo<span class=\"token punctuation\">}<\/span> className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-logo\"<\/span> alt<span class=\"token operator\">=<\/span><span class=\"token string\">\"logo\"<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n          Edit <span class=\"token operator\">&lt;<\/span>code<span class=\"token operator\">&gt;<\/span>src<span class=\"token operator\">\/<\/span>App<span class=\"token punctuation\">.<\/span>js<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>code<span class=\"token operator\">&gt;<\/span> and save to reload<span class=\"token punctuation\">.<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>a\r\n          className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-link\"<\/span>\r\n          href<span class=\"token operator\">=<\/span><span class=\"token string\">\"https:\/\/reactjs.org\"<\/span>\r\n          target<span class=\"token operator\">=<\/span><span class=\"token string\">\"_blank\"<\/span>\r\n          rel<span class=\"token operator\">=<\/span><span class=\"token string\">\"noopener noreferrer\"<\/span>\r\n        <span class=\"token operator\">&gt;<\/span>\r\n          Learn React\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>a<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>header<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u4f60\u5c06\u4f7f\u7528\u8fd9\u4e9b\u6765\u8bbe\u7f6e\u4f60\u7684\u7f51\u7edc\u5e94\u7528\u4e2d\u7684\u8def\u7531\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u5c06\u521a\u521a\u521b\u5efa\u7684SubscriberFeed\u7ec4\u4ef6\u6dfb\u52a0\u5230\u5bfc\u5165\u7684\u7a81\u51fa\u663e\u793a\u7684\u884c\u4e2d\u3002<\/p>\n<div>\u8bf7\u7528\u4e2d\u6587\u5c06\u4ee5\u4e0b\u5185\u5bb9\u8fdb\u884c\u6539\u5199\uff0c\u53ea\u9700\u8981\u63d0\u4f9b\u4e00\u4e2a\u9009\u9879\uff1a<br \/>\n jwt-storage-tutorial\/front-end\/src\/App.js\u3002<\/p>\n<p>jwt-storage-tutorial\/front-end\/src\/App.js\u6587\u4ef6<\/p><\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> BrowserRouter<span class=\"token punctuation\">,<\/span> Route<span class=\"token punctuation\">,<\/span> Switch <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n<mark><span class=\"token keyword\">import<\/span> SubscriberFeed <span class=\"token keyword\">from<\/span> <span class=\"token string\">\".\/components\/SubscriberFeed\"<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>header className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>img src<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>logo<span class=\"token punctuation\">}<\/span> className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-logo\"<\/span> alt<span class=\"token operator\">=<\/span><span class=\"token string\">\"logo\"<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n          Edit <span class=\"token operator\">&lt;<\/span>code<span class=\"token operator\">&gt;<\/span>src<span class=\"token operator\">\/<\/span>App<span class=\"token punctuation\">.<\/span>js<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>code<span class=\"token operator\">&gt;<\/span> and save to reload<span class=\"token punctuation\">.<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>a\r\n          className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-link\"<\/span>\r\n          href<span class=\"token operator\">=<\/span><span class=\"token string\">\"https:\/\/reactjs.org\"<\/span>\r\n          target<span class=\"token operator\">=<\/span><span class=\"token string\">\"_blank\"<\/span>\r\n          rel<span class=\"token operator\">=<\/span><span class=\"token string\">\"noopener noreferrer\"<\/span>\r\n        <span class=\"token operator\">&gt;<\/span>\r\n          Learn React\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>a<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>header<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u4f60\u73b0\u5728\u5df2\u7ecf\u51c6\u5907\u597d\u521b\u5efa\u4e3b\u5e94\u7528\u7a0b\u5e8f\u548c\u7f51\u9875\u8def\u7531\u4e86\u3002<\/p>\n<p>\u4ecd\u7136\u5728src\/App.js\u4e2d\uff0c\u5220\u9664\u8fd4\u56de\u7684JSX\u884c\uff08\u5373\u5728return\u5173\u952e\u5b57\u4e4b\u540e\u7684\u62ec\u53f7\u5185\u7684\u6240\u6709\u5185\u5bb9\uff09\u5e76\u7528\u9ad8\u4eae\u7684\u884c\u66ff\u6362\u3002<\/p>\n<div>jwt-storage-tutorial\/front-end\/src\/App.js\u7684\u4e2d\u6587\u91ca\u4e49\u5982\u4e0b\uff1a<\/p>\n<p>\u4ee4\u724c\u5b58\u50a8\u6559\u7a0b\/\u524d\u7aef\/src\/App.js<\/p><\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> BrowserRouter<span class=\"token punctuation\">,<\/span> Route<span class=\"token punctuation\">,<\/span> Switch <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> SubscriberFeed <span class=\"token keyword\">from<\/span> <span class=\"token string\">\".\/components\/SubscriberFeed\"<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <mark><span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App\"<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n      <mark><span class=\"token operator\">&lt;<\/span>h1 className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n        <mark><span class=\"token constant\">JWT<\/span><span class=\"token operator\">-<\/span>Storage<span class=\"token operator\">-<\/span>Tutorial Application<\/mark>\r\n      <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span><\/mark>\r\n    <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span><\/mark>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p><div class=\"App\">\u6807\u7b7e\u62e5\u6709\u4e00\u4e2aclassName\u5c5e\u6027\u4e3aApp\uff0c\u5176\u4e2d\u5305\u542b\u4e00\u4e2a&lt;h1&gt;\u6807\u7b7e\uff0c\u663e\u793a\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u540d\u79f0\u3002<\/p>\n<p>\u5728&lt;h1&gt;\u6807\u7b7e\u4e0b\u65b9\uff0c\u6dfb\u52a0\u4e00\u4e2a BrowserRouter \u7ec4\u4ef6\uff0c\u8be5\u7ec4\u4ef6\u4f7f\u7528 Switch \u7ec4\u4ef6\u5c06\u5305\u542b SubscriberFeed \u7ec4\u4ef6\u7684 Route \u7ec4\u4ef6\u8fdb\u884c\u5305\u88c5\u3002<\/p>\n<div>\u5c06\u4e0b\u8ff0\u6587\u4ef6\u8fdb\u884c\u4e2d\u6587\u672c\u5730\u5316\uff0c\u4ec5\u9700\u4e00\u79cd\u9009\u62e9\uff1a<br \/>\njwt-storage-tutorial\/front-end\/src\/App.js<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> BrowserRouter<span class=\"token punctuation\">,<\/span> Route<span class=\"token punctuation\">,<\/span> Switch <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> SubscriberFeed <span class=\"token keyword\">from<\/span> <span class=\"token string\">\".\/components\/SubscriberFeed\"<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>h1 className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token constant\">JWT<\/span><span class=\"token operator\">-<\/span>Storage<span class=\"token operator\">-<\/span>Tutorial Application\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n      <mark><span class=\"token operator\">&lt;<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span><\/mark>\r\n        <mark><span class=\"token operator\">&lt;<\/span>Switch<span class=\"token operator\">&gt;<\/span><\/mark>\r\n          <mark><span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/subscriber-feed\"<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n            <mark><span class=\"token operator\">&lt;<\/span>SubscriberFeed <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n          <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span><\/mark>\r\n        <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Switch<span class=\"token operator\">&gt;<\/span><\/mark>\r\n      <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span><\/mark>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u8fd9\u4e9b\u65b0\u884c\u5141\u8bb8\u60a8\u5b9a\u4e49\u5e94\u7528\u7a0b\u5e8f\u7684\u8def\u7531\u3002BrowserRouter\u7ec4\u4ef6\u5c01\u88c5\u4e86\u60a8\u5b9a\u4e49\u7684\u8def\u5f84\u3002Switch\u7ec4\u4ef6\u786e\u4fdd\u8fd4\u56de\u7684\u8def\u5f84\u662f\u4e0e\u7528\u6237\u5bfc\u822a\u5230\u7684\u8def\u5f84\u5339\u914d\u7684\u7b2c\u4e00\u6761\u8def\u7531\uff0c\u800cRoute\u7ec4\u4ef6\u5b9a\u4e49\u7279\u5b9a\u7684\u8def\u7531\u540d\u79f0\u3002<\/p>\n<p>\u6700\u540e\uff0c\u60a8\u5c06\u4f7f\u7528CSS\u4e3a\u5e94\u7528\u7a0b\u5e8f\u6dfb\u52a0\u586b\u5145\uff0c\u4ee5\u4f7f\u6807\u9898\u548c\u7ec4\u4ef6\u5c45\u4e2d\u548c\u6f02\u4eae\u3002\u5728\u6700\u5916\u5c42\u7684&lt;div&gt;\u6807\u7b7e\u7684className\u5c5e\u6027\u4e0a\u6dfb\u52a0\u4e00\u4e2a\u5305\u88c5\u5668\u3002<\/p>\n<div>\u8bf7\u4e3a\uc800\ud76c\u6587\u4ef6\u4e2d\u7684&#8217;jwt-storage-tutorial\/front-end\/src\/App.js&#8217;\u63d0\u4f9b\u4e2d\u6587\u7684\u540c\u4e49\u8bcd\u3002<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> BrowserRouter<span class=\"token punctuation\">,<\/span> Route<span class=\"token punctuation\">,<\/span> Switch <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> SubscriberFeed <span class=\"token keyword\">from<\/span> <span class=\"token string\">\".\/components\/SubscriberFeed\"<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App <mark>wrapper<\/mark>\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>h1 className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token constant\">JWT<\/span><span class=\"token operator\">-<\/span>Storage<span class=\"token operator\">-<\/span>Tutorial Application\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/subscriber-feed\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n            <span class=\"token operator\">&lt;<\/span>SubscriberFeed <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u4fdd\u5b58\u5e76\u5173\u95edApp.js\u6587\u4ef6\u3002<\/p>\n<p>\u6253\u5f00App.css\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> src\/App.css\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u4f60\u4f1a\u5728\u8fd9\u4e2a\u6587\u4ef6\u4e2d\u770b\u5230\u73b0\u6709\u7684CSS\u3002\u5220\u9664\u6587\u4ef6\u4e2d\u7684\u6240\u6709\u5185\u5bb9\u3002<\/p>\n<p>\u7136\u540e\uff0c\u6dfb\u52a0\u4e0b\u5217\u4ee3\u7801\u6765\u5b9a\u4e49\u5305\u88c5\u6837\u5f0f:<\/p>\n<div>jwt-storage-tutorial\/front-end\/src\/App.css \u53ef\u4ee5\u88ab\u7ffb\u8bd1\u4e3a\u201cjwt-storage-tutorial\/front-end\/src\/App.css\u201d\u3002<\/div>\n<pre class=\"post-pre\"><code><mark><span class=\"token punctuation\">.<\/span>wrapper <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark><span class=\"token literal-property property\">padding<\/span><span class=\"token operator\">:<\/span> 20px<span class=\"token punctuation\">;<\/span><\/mark>\r\n    <mark>text<span class=\"token operator\">-<\/span>align<span class=\"token operator\">:<\/span> center<span class=\"token punctuation\">;<\/span><\/mark>\r\n<mark><span class=\"token punctuation\">}<\/span><\/mark>\r\n<\/code><\/pre>\n<p>\u4f60\u5c06wrapper\u7c7b\u7684text-align\u5c5e\u6027\u8bbe\u7f6e\u4e3acenter\u6765\u4f7f\u5e94\u7528\u7a0b\u5e8f\u4e2d\u7684\u6587\u672c\u5c45\u4e2d\u3002\u4f60\u8fd8\u901a\u8fc7\u5c06padding\u5c5e\u6027\u8bbe\u7f6e\u4e3a20px\uff0c\u4e3awrapper\u7c7b\u6dfb\u52a0\u4e8620\u50cf\u7d20\u7684\u5185\u8fb9\u8ddd\u3002<\/p>\n<p>\u4fdd\u5b58\u5e76\u5173\u95edApp.css\u6587\u4ef6\u3002<\/p>\n<p>\u4f60\u53ef\u80fd\u4f1a\u770b\u5230\u4f60\u7684React\u9996\u9875\u66f4\u65b0\u4e86\u65b0\u7684\u6837\u5f0f\u3002\u5bfc\u822a\u5230http:\/\/localhost:3000\/subscriber-feed\u6765\u67e5\u770b\u8ba2\u9605\u8005\u52a8\u6001\uff0c\u73b0\u5728\u5df2\u7ecf\u53ef\u89c1\u3002<\/p>\n<div>\n                            <img decoding=\"async\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/6564666ea4b2f92e6c7266b0\/122-0.png\" class='post-images' alt=\"Screencapture of the React application with a visible subscriber feed page\" title=\"\">\n                        <\/div>\n<p>\u8def\u7531\u6309\u9884\u671f\u5de5\u4f5c\uff0c\u4f46\u6240\u6709\u8bbf\u5ba2\u90fd\u53ef\u4ee5\u8bbf\u95ee\u8ba2\u9605\u8005\u52a8\u6001\u3002\u4e3a\u4e86\u786e\u4fdd\u8ba2\u9605\u8005\u52a8\u6001\u4ec5\u5bf9\u7ecf\u8fc7\u8eab\u4efd\u9a8c\u8bc1\u7684\u7528\u6237\u53ef\u89c1\uff0c\u60a8\u9700\u8981\u4e3a\u7528\u6237\u521b\u5efa\u4e00\u4e2a\u767b\u5f55\u9875\u9762\uff0c\u8ba9\u4ed6\u4eec\u901a\u8fc7\u7528\u6237\u540d\u548c\u5bc6\u7801\u8fdb\u884c\u9a8c\u8bc1\u3002<\/p>\n<p>\u5728\u4f60\u7684\u7ec4\u4ef6\u76ee\u5f55\u4e2d\u6253\u5f00\u4e00\u4e2a\u65b0\u7684Login.js\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> src\/components\/Login.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5c06\u4ee5\u4e0b\u884c\u6dfb\u52a0\u5230\u65b0\u6587\u4ef6\u4e2d\uff1a<\/p>\n<div>jwt-storage-tutorial\/front-end\/src\/components\/Login.js \u7684\u7ec4\u4ef6<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> React <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">'login-wrapper'<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>h1<span class=\"token operator\">&gt;<\/span>Login<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>form<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>Username<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>input type<span class=\"token operator\">=<\/span><span class=\"token string\">\"text\"<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>Password<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>input type<span class=\"token operator\">=<\/span><span class=\"token string\">\"password\"<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>button type<span class=\"token operator\">=<\/span><span class=\"token string\">\"submit\"<\/span><span class=\"token operator\">&gt;<\/span>Submit<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>button<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>form<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n<\/code><\/pre>\n<p>\u4f60\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u8868\u5355\uff0c\u5176\u4e2d\u5305\u542b\u4e00\u4e2a &lt;h1&gt; \u6807\u7b7e\u4f5c\u4e3a\u6807\u9898\u3001\u4e24\u4e2a\u8f93\u5165\u6846\uff08\u7528\u6237\u540d\u548c\u5bc6\u7801\uff09\u4ee5\u53ca\u4e00\u4e2a\u63d0\u4ea4\u6309\u94ae\u3002\u4f60\u5c06\u8868\u5355\u653e\u5728\u4e00\u4e2a &lt;div&gt; \u6807\u7b7e\u4e2d\uff0c\u5e76\u7ed9\u5b83\u4e00\u4e2a\u7c7b\u540d\u4e3a login-wrapper\uff0c\u4ee5\u4fbf\u5728 App.css \u6587\u4ef6\u4e2d\u8fdb\u884c\u6837\u5f0f\u8bbe\u7f6e\u3002<\/p>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u6253\u5f00\u9879\u76ee\u6839\u76ee\u5f55\u4e2d\u7684App.css\u6587\u4ef6\uff0c\u4e3a\u60a8\u7684\u767b\u5f55\u7ec4\u4ef6\u8bbe\u7f6e\u6837\u5f0f\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> src\/App.css\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5c06\u4ee5\u4e0bCSS\u884c\u6dfb\u52a0\u5230login-wrapper\u7c7b\u7684\u6837\u5f0f\u4e2d\u3002<\/p>\n<div>jwt-storage-tutorial\/front-end\/src\/App.css \u7684\u5185\u5bb9\u8fdb\u884c\u4e2d\u6587\u542b\u4e49\u7684\u590d\u8ff0\u662f\u4ec0\u4e48\uff1a<\/div>\n<pre class=\"post-pre\"><code><span class=\"token operator\">...<\/span>\r\n\r\n<span class=\"token punctuation\">.<\/span>login<span class=\"token operator\">-<\/span>wrapper <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token literal-property property\">display<\/span><span class=\"token operator\">:<\/span> flex<span class=\"token punctuation\">;<\/span>\r\n    flex<span class=\"token operator\">-<\/span>direction<span class=\"token operator\">:<\/span> column<span class=\"token punctuation\">;<\/span>\r\n    align<span class=\"token operator\">-<\/span>items<span class=\"token operator\">:<\/span> center<span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n<\/code><\/pre>\n<p>\u4f60\u53ef\u4ee5\u901a\u8fc7\u4f7f\u7528flex\u7684display\u5c5e\u6027\u548calign-items\u5c5e\u6027\uff0c\u5c06\u7ec4\u4ef6\u5c45\u4e2d\u5728\u9875\u9762\u4e0a\u3002\u7136\u540e\uff0c\u4f60\u5c06flex-direction\u8bbe\u7f6e\u4e3acolumn\uff0c\u8fd9\u5c06\u4f7f\u5143\u7d20\u5728\u5782\u76f4\u7684\u5217\u4e2d\u5bf9\u9f50\u3002<\/p>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u6700\u540e\uff0c\u4f60\u5c06\u4f7f\u7528useState Hook\u5c06Login\u7ec4\u4ef6\u6e32\u67d3\u5728App.js\u4e2d\uff0c\u5e76\u5c06\u4ee4\u724c\u5b58\u50a8\u5728\u5185\u5b58\u4e2d\u3002\u6253\u5f00App.js\u6587\u4ef6\uff1a<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> src\/App.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5c06\u7a81\u51fa\u663e\u793a\u7684\u884c\u6dfb\u52a0\u5230\u6587\u4ef6\u4e2d\u3002<\/p>\n<div>\u8fd9\u662f\u4e00\u4e2a\u6307\u5411jwt-storage-tutorial\u9879\u76ee\u7684\u524d\u7aef\u6e90\u7801\u6587\u4ef6\uff0c\u4f4d\u7f6e\u662f\u5728front-end\/src\/App.js\u3002<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<mark><span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useState <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><\/mark>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> BrowserRouter<span class=\"token punctuation\">,<\/span> Route<span class=\"token punctuation\">,<\/span> Switch <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> SubscriberFeed <span class=\"token keyword\">from<\/span> <span class=\"token string\">\".\/components\/SubscriberFeed\"<\/span><span class=\"token punctuation\">;<\/span>\r\n<mark><span class=\"token keyword\">import<\/span> Login <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/components\/Login'<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <mark><span class=\"token keyword\">const<\/span> <span class=\"token punctuation\">[<\/span>token<span class=\"token punctuation\">,<\/span> setToken<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">useState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n\r\n  <mark><span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>token<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark><span class=\"token keyword\">return<\/span> <span class=\"token operator\">&lt;<\/span>Login setToken<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>setToken<span class=\"token punctuation\">}<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span><\/mark>\r\n\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App wrapper\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>h1 className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token constant\">JWT<\/span><span class=\"token operator\">-<\/span>Storage<span class=\"token operator\">-<\/span>Tutorial Application\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/subscriber-feed\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n            <span class=\"token operator\">&lt;<\/span>SubscriberFeed <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u9996\u5148\uff0c\u4f60\u4ece React \u5305\u4e2d\u5bfc\u5165 useState \u94a9\u5b50\u3002<\/p>\n<p>\u60a8\u8fd8\u5c06\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a\u65b0\u4ee4\u724c\u72b6\u6001\u53d8\u91cf\uff0c\u4ee5\u5b58\u50a8\u767b\u5f55\u8fc7\u7a0b\u4e2d\u83b7\u53d6\u7684\u4ee4\u724c\u4fe1\u606f\u3002\u5728\u6b65\u9aa45\u4e2d\uff0c\u60a8\u5c06\u901a\u8fc7\u4f7f\u7528\u6d4f\u89c8\u5668\u5b58\u50a8\u6765\u6539\u8fdb\u6b64\u8bbe\u7f6e\uff0c\u4ee5\u6301\u4e45\u5316\u8eab\u4efd\u9a8c\u8bc1\u72b6\u6001\u3002\u5728\u6b65\u9aa47\u4e2d\uff0c\u60a8\u5c06\u8fdb\u4e00\u6b65\u52a0\u5f3a\u6301\u4e45\u5316\u65b9\u6cd5\uff0c\u901a\u8fc7\u4f7f\u7528HTTP-only cookie\u5b89\u5168\u5730\u5b58\u50a8\u8eab\u4efd\u9a8c\u8bc1\u72b6\u6001\u3002<\/p>\n<p>\u4f60\u8fd8\u8981\u5bfc\u5165Login\u7ec4\u4ef6\uff0c\u5982\u679ctoken\u7684\u503c\u4e3a\u5047\u503c\uff0c\u5219\u663e\u793a\u767b\u5f55\u9875\u9762\u3002if\u8bed\u53e5\u58f0\u660e\uff0c\u5982\u679ctoken\u4e3a\u5047\u503c\uff0c\u5219\u8981\u6c42\u7528\u6237\u767b\u5f55\uff0c\u5982\u679c\u4ed6\u4eec\u6ca1\u6709\u901a\u8fc7\u8eab\u4efd\u9a8c\u8bc1\u3002\u4f60\u5c06setToken\u51fd\u6570\u4f5c\u4e3aprop\u4f20\u9012\u7ed9Login\u7ec4\u4ef6\u3002<\/p>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u7136\u540e\uff0c\u5237\u65b0\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u9875\u9762\u4ee5\u52a0\u8f7d\u65b0\u5efa\u7684\u767b\u5f55\u9875\u9762\u3002\u7531\u4e8e\u76ee\u524d\u5c1a\u672a\u5b9e\u73b0\u8bbe\u7f6e\u4ee4\u724c\u7684\u529f\u80fd\uff0c\u5e94\u7528\u7a0b\u5e8f\u53ea\u4f1a\u663e\u793a\u767b\u5f55\u9875\u9762\u3002<\/p>\n<div>\n                            <img decoding=\"async\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/6564666ea4b2f92e6c7266b0\/148-0.png\" class='post-images' alt=\"Screencapture of the React application login form showing username and password input boxes\" title=\"\">\n                        <\/div>\n<p>\u5728\u8fd9\u4e2a\u6b65\u9aa4\u4e2d\uff0c\u60a8\u66f4\u65b0\u4e86\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\uff0c\u6dfb\u52a0\u4e86\u4e00\u4e2a\u767b\u5f55\u9875\u9762\u548c\u4e00\u4e2a\u79c1\u5bc6\u7ec4\u4ef6\uff0c\u8fd9\u4e2a\u7ec4\u4ef6\u5728\u7528\u6237\u767b\u5f55\u4e4b\u524d\u5c06\u53d7\u5230\u672a\u6388\u6743\u7528\u6237\u7684\u4fdd\u62a4\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u60a8\u5c06\u4f7f\u7528NodeJS\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u540e\u7aef\u5e94\u7528\u7a0b\u5e8f\uff0c\u5e76\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u767b\u5f55\u8def\u7531\uff0c\u5728\u60a8\u7684\u524d\u7aef\u5e94\u7528\u7a0b\u5e8f\u4e0a\u8c03\u7528\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u3002<\/p>\n<h2>\u7b2c\u56db\u6b65 &#8211; \u521b\u5efa\u4e00\u4e2a\u4ee4\u724cAPI<\/h2>\n<p>\u5728\u8fd9\u4e00\u6b65\u4e2d\uff0c\u60a8\u5c06\u4e3a\u524d\u4e00\u6b65\u8bbe\u7f6e\u7684\u524d\u7aefReact\u5e94\u7528\u7a0b\u5e8f\u521b\u5efa\u4e00\u4e2aNode\u670d\u52a1\u5668\u4f5c\u4e3a\u540e\u7aef\u3002\u60a8\u5c06\u4f7f\u7528Node\u670d\u52a1\u5668\u521b\u5efa\u5e76\u63d0\u4f9b\u4e00\u4e2aAPI\uff0c\u8be5API\u5728\u524d\u7aef\u7528\u6237\u901a\u8fc7\u9a8c\u8bc1\u540e\u8fd4\u56de\u4e00\u4e2a\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u3002\u5728\u672c\u6b65\u9aa4\u7ed3\u675f\u65f6\uff0c\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5c06\u5177\u6709\u4e00\u4e2a\u5de5\u4f5c\u7684\u767b\u5f55\u9875\u9762\uff0c\u4ec5\u5728\u6210\u529f\u9a8c\u8bc1\u540e\u624d\u53ef\u7528\u7684\u79c1\u6709\u8d44\u6e90\u4ee5\u53ca\u901a\u8fc7API\u8c03\u7528\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u7684\u540e\u7aef\u670d\u52a1\u5668\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>\u4f60\u5c06\u4f7f\u7528Express\u6846\u67b6\u6784\u5efa\u670d\u52a1\u5668\uff0c\u5e76\u4f7f\u7528cors\u5305\u4e3a\u6240\u6709\u8def\u7531\u542f\u7528\u8de8\u57df\u8d44\u6e90\u5171\u4eab\u3002\u8fd9\u6837\uff0c\u4f60\u5c31\u53ef\u4ee5\u5728\u6ca1\u6709CORS\u9519\u8bef\u7684\u60c5\u51b5\u4e0b\u6d4b\u8bd5\u548c\u5f00\u53d1\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<div class=\"post-conf-warning\">\n<p class=\"post-warning\">\n<p class=\"post-conf-desc\">Warning<\/p>\n<div>\u8b66\u544a\uff1a\u4e3a\u4e86\u6559\u5b66\u76ee\u7684\uff0c\u5728\u5f00\u53d1\u73af\u5883\u4e2d\u542f\u7528\u4e86CORS\u3002\u7136\u800c\uff0c\u5728\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f\u4e2d\u4e3a\u6240\u6709\u8def\u7531\u542f\u7528CORS\u5c06\u5bfc\u81f4\u5b89\u5168\u6f0f\u6d1e\u3002<\/div>\n<\/div>\n<p>\u521b\u5efa\u5e76\u79fb\u52a8\u5230\u4e00\u4e2a\u540d\u4e3a\u540e\u7aef\u7684\u6587\u4ef6\u5939\uff0c\u7528\u4e8e\u5b58\u653e\u4f60\u7684Node\u9879\u76ee\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">mkdir<\/span> \/app\/jwt-storage-tutorial\/back-end\r\n<\/li><li data-prefix=\"$\"><span class=\"token builtin class-name\">cd<\/span> \/app\/jwt-storage-tutorial\/back-end\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5728\u65b0\u7684\u76ee\u5f55\u4e2d\uff0c\u521d\u59cb\u5316\u8282\u70b9\u9879\u76ee\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">npm<\/span> init <span class=\"token parameter variable\">-y<\/span>\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>init\u547d\u4ee4\u544a\u8bc9npm\u547d\u4ee4\u884c\u5de5\u5177\u5728\u8fd0\u884c\u8be5\u547d\u4ee4\u7684\u76ee\u5f55\u4e2d\u521b\u5efa\u4e00\u4e2a\u65b0\u7684Node\u9879\u76ee\u3002-y\u6807\u5fd7\u4f7f\u7528\u4ea4\u4e92\u5f0f\u547d\u4ee4\u884c\u5de5\u5177\u5728\u521b\u5efa\u65b0\u9879\u76ee\u65f6\uff0c\u5bf9\u6240\u6709\u521d\u59cb\u5316\u95ee\u9898\u4f7f\u7528\u9ed8\u8ba4\u503c\u3002\u4ee5\u4e0b\u662f\u4f7f\u7528-y\u6807\u5fd7\u8fd0\u884cinit\u547d\u4ee4\u7684\u8f93\u51fa\uff1a<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>Wrote to \/home\/nodejs\/jwt-storage-tutorial\/back-end\/package.json:\r\n\r\n{\r\n  \"name\": \"back-end\",\r\n  \"version\": \"1.0.0\",\r\n  \"description\": \"\",\r\n  \"main\": \"index.js\",\r\n  \"scripts\": {\r\n    \"test\": \"echo \\\"Error: no test specified\\\" &amp;&amp; exit 1\"\r\n  },\r\n  \"keywords\": [],\r\n  \"author\": \"\",\r\n  \"license\": \"ISC\"\r\n}\r\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\uff0c\u5c06express\u548ccors\u6a21\u5757\u5b89\u88c5\u5728\u540e\u7aef\u9879\u76ee\u76ee\u5f55\u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">npm<\/span> <span class=\"token function\">install<\/span> express cors\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u4ee5\u4e0b\u8f93\u51fa\u7684\u67d0\u79cd\u53d8\u4f53\u5c06\u51fa\u73b0\u5728\u7ec8\u7aef\u4e0a\u3002<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>added 59 packages, and audited 60 packages in 3s\r\n\r\n7 packages are looking for funding\r\n  run `npm fund` for details\r\n\r\nfound 0 vulnerabilities\r\n<\/code><\/pre>\n<p>\u65b0\u5efa\u4e00\u4e2aindex.js\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> index.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5c06\u4ee5\u4e0b\u4ee3\u7801\u6dfb\u52a0\u5230\u5bfc\u5165express\u6a21\u5757\u5e76\u901a\u8fc7\u8c03\u7528express()\u65b9\u6cd5\u4ee5\u53ca\u5c06\u7ed3\u679c\u5b58\u50a8\u5728\u540d\u4e3aapp\u7684\u53d8\u91cf\u4e2d\u6765\u521d\u59cb\u5316\u4e00\u4e2a\u65b0\u7684Express\u5e94\u7528\u7a0b\u5e8f\u7684\u884c\u3002<\/p>\n<div>jwt-storage-tutorial\/back-end\/index.js\u7684\u7ffb\u8bd1<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">const<\/span> express <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'express'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">const<\/span> app <span class=\"token operator\">=<\/span> <span class=\"token function\">express<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\uff0c\u4f7f\u7528\u9ad8\u4eae\u663e\u793a\u7684\u4ee3\u7801\u884c\u5c06 CORS \u6dfb\u52a0\u4e3a\u5e94\u7528\u7a0b\u5e8f\u7684\u4e2d\u95f4\u4ef6\u3002<\/p>\n<div>\u5c06\u4ee5\u4e0b\u82f1\u6587\u53e5\u5b50\u6539\u5199\u4e3a\u4e2d\u6587\u539f\u751f\u8868\u8fbe\uff0c\u5e76\u63d0\u4f9b\u4e00\u79cd\u9009\u9879\uff1a<br \/>\njwt-storage-tutorial\/back-end\/index.js<br \/>\nJWT \u5b58\u50a8\u6559\u7a0b\/\u540e\u7aef\/index.js<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">const<\/span> express <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'express'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<mark><span class=\"token keyword\">const<\/span> cors <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cors'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n\r\n<span class=\"token keyword\">const<\/span> app <span class=\"token operator\">=<\/span> <span class=\"token function\">express<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<mark>app<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cors<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n<\/code><\/pre>\n<p>\u4f60\u9700\u8981\u5bfc\u5165cors\u6a21\u5757\uff0c\u7136\u540e\u4f7f\u7528use\u65b9\u6cd5\u5c06\u5176\u6dfb\u52a0\u5230app\u5bf9\u8c61\u4e2d\u3002<\/p>\n<p>\u7136\u540e\u5c06\u7a81\u51fa\u663e\u793a\u7684\u884c\u6dfb\u52a0\u5230\u5b9a\u4e49\u5904\u7406\u7a0b\u5e8f\u7684\/login\u8def\u5f84\uff0c\u4ee5\u5411\u767b\u5f55\u7684\u7528\u6237\u8fd4\u56de\u4e00\u4e2a\u4ee4\u724c\u3002<\/p>\n<div>\u8bf7\u628ajwt-storage-tutorial\/back-end\/index.js\u7528\u4e2d\u6587\u672c\u5730\u5316\uff1a<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">const<\/span> express <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'express'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">const<\/span> cors <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cors'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">const<\/span> app <span class=\"token operator\">=<\/span> <span class=\"token function\">express<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cors<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<mark>app<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'\/login'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark>res<span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">token<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"This is a secret token\"<\/span><\/mark>\r\n    <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n<mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n<\/code><\/pre>\n<p>\u4f60\u53ef\u4ee5\u4f7f\u7528app.use()\u65b9\u6cd5\u6765\u4e3a\u8def\u7531\u5b9a\u4e49\u4e00\u4e2a\u8bf7\u6c42\u5904\u7406\u7a0b\u5e8f\u3002\u8fd9\u4e2a\u8def\u7531\u5c06\u5141\u8bb8\u4f60\u4ece\u521a\u521a\u6784\u5efa\u7684\u524d\u7aef\u5e94\u7528\u4e2d\u53d1\u9001\u7528\u6237\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801\u8fdb\u884c\u8ba4\u8bc1\u3002\u4f5c\u4e3a\u56de\u5e94\uff0c\u4f60\u5c06\u63d0\u4f9b\u7528\u6237\u7684\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\uff0c\u4ee5\u4fbf\u7528\u6237\u53ef\u4ee5\u8fdb\u884c\u7ecf\u8fc7\u8ba4\u8bc1\u7684\u540e\u7aef\u5e94\u7528\u8c03\u7528\u3002<\/p>\n<p>app.use\u65b9\u6cd5\u7684\u9996\u4e2a\u53c2\u6570\u662f\u5e94\u7528\u7a0b\u5e8f\u63a5\u53d7\u8bf7\u6c42\u7684\u8def\u7531\u3002\u7b2c\u4e8c\u4e2a\u53c2\u6570\u662f\u4e00\u4e2a\u56de\u8c03\u51fd\u6570\uff0c\u8be6\u7ec6\u8bf4\u660e\u5982\u4f55\u5904\u7406\u5e94\u7528\u7a0b\u5e8f\u63a5\u6536\u5230\u7684\u8bf7\u6c42\u3002\u56de\u8c03\u51fd\u6570\u6709\u4e24\u4e2a\u53c2\u6570\uff1a\u4e00\u4e2areq\u53c2\u6570\u5305\u542b\u8bf7\u6c42\u6570\u636e\uff0c\u4e00\u4e2ares\u53c2\u6570\u5305\u542b\u54cd\u5e94\u6570\u636e\u3002<\/p>\n<div class=\"post-conf-note\">\n<p class=\"post-note\">\n<p class=\"post-conf-desc\">Note<\/p>\n<div>\u6ce8\u610f\uff1a\u7528\u6237\u5728\u4f7f\u7528\u540e\u7aefAPI\u767b\u5f55\u65f6\uff0c\u60a8\u6ca1\u6709\u68c0\u67e5\u51ed\u636e\u7684\u51c6\u786e\u6027\u3002\u51fa\u4e8e\u7b80\u6d01\u8d77\u89c1\uff0c\u672c\u6b65\u9aa4\u672a\u5305\u542b\u5728\u5185\uff0c\u4f46\u662f\u751f\u4ea7\u5e94\u7528\u7a0b\u5e8f\u901a\u5e38\u4f1a\u67e5\u8be2\u6570\u636e\u5e93\u4ee5\u68c0\u67e5\u7528\u6237\u662f\u5426\u63d0\u4f9b\u4e86\u6b63\u786e\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801\uff0c\u7136\u540e\u518d\u53d1\u51fa\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u3002<\/div>\n<\/div>\n<p>\u6700\u540e\uff0c\u4f7f\u7528app.listen\u51fd\u6570\u5c06\u670d\u52a1\u5668\u8fd0\u884c\u57288080\u7aef\u53e3\u4e0a\uff0c\u5e76\u6dfb\u52a0\u9ad8\u4eae\u7684\u884c\u4ee3\u7801\u3002<\/p>\n<div>jwt-storage-tutorial\/back-end\/index.js\u7684\u5185\u5bb9\u8fdb\u884c\u91ca\u4e49<\/div>\n<pre class=\"post-pre\"><code>\r\n<span class=\"token keyword\">const<\/span> express <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'express'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">const<\/span> cors <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cors'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">const<\/span> app <span class=\"token operator\">=<\/span> <span class=\"token function\">express<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cors<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'\/login'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n    res<span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">token<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"This is a secret token\"<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<mark>app<span class=\"token punctuation\">.<\/span><span class=\"token function\">listen<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">8080<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token template-string\"><span class=\"token template-punctuation string\">`<\/span><span class=\"token string\">API is active on http:\/\/localhost:8080<\/span><span class=\"token template-punctuation string\">`<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n<\/code><\/pre>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u8981\u4f7f\u7528PM2\u8fd0\u884c\u60a8\u7684\u540e\u7aef\u5e94\u7528\u7a0b\u5e8f\uff0c\u8bf7\u521b\u5efa\u4e00\u4e2a\u65b0\u7684backend\/ecosystem.config.js\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> ecosystem.config.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5c06\u4ee5\u4e0b\u914d\u7f6e\u4ee3\u7801\u6dfb\u52a0\u5230\u65b0\u521b\u5efa\u7684\u540e\u7aef \/ ecosystem.config.js \u6587\u4ef6\u4e2d\uff1a<\/p>\n<div>jwt-storage-tutorial\/back-end\/ecosystem.config.js\u7684\u89e3\u91ca\u6307\u5357\u3002<\/div>\n<pre class=\"post-pre\"><code>module<span class=\"token punctuation\">.<\/span>exports <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token literal-property property\">apps<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span>\r\n    <span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">name<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'back-end'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">cwd<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'\/app\/jwt-storage-tutorial\/back-end'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">script<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'node'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">args<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'index.js'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">watch<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">'index.js'<\/span><span class=\"token punctuation\">]<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>\r\n  <span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">,<\/span>\r\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>PM2\u5c06\u4f7f\u7528\u4e0e\u524d\u7aef\u5e94\u7528\u7c7b\u4f3c\u7684\u914d\u7f6e\u53c2\u6570\u6765\u7ba1\u7406\u540e\u7aef\u5e94\u7528\u3002<\/p>\n<p>\u5f53\u4f60\u5728\u914d\u7f6e\u6587\u4ef6\u4e2d\u5c06\u89c2\u5bdf\uff08watch\uff09\u53c2\u6570\u8bbe\u7f6e\u4e3a\u6bcf\u6b21\u5bf9\u6587\u4ef6\u8fdb\u884c\u66f4\u6539\u65f6\u81ea\u52a8\u91cd\u65b0\u52a0\u8f7d\u5e94\u7528\u7a0b\u5e8f\u3002\u89c2\u5bdf\u53c2\u6570\u662f\u4e00\u4e2a\u6709\u7528\u7684\u5f00\u53d1\u529f\u80fd\uff0c\u5b83\u5728\u4ee3\u7801\u66f4\u6539\u65f6\u4f1a\u5728\u6d4f\u89c8\u5668\u4e2d\u66f4\u65b0\u7ed3\u679c\u3002\u5bf9\u4e8e\u524d\u7aef\u5e94\u7528\u7a0b\u5e8f\uff0c\u4f60\u4e0d\u9700\u8981\u89c2\u5bdf\u53c2\u6570\uff0c\u56e0\u4e3a\u4f60\u4f7f\u7528\u4e86\u5177\u6709\u9ed8\u8ba4\u81ea\u52a8\u91cd\u65b0\u52a0\u8f7d\u529f\u80fd\u7684react-scripts\u8fd0\u884c\u5b83\u3002\u7136\u800c\uff0c\u4f60\u7684\u540e\u7aef\u5e94\u7528\u7a0b\u5e8f\u5c06\u4f7f\u7528node\u8fd0\u884c\u65f6\uff0c\u5b83\u6ca1\u6709\u8fd9\u4e2a\u9ed8\u8ba4\u529f\u80fd\u3002<\/p>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u73b0\u5728\u4f60\u53ef\u4ee5\u4f7f\u7528pm2\u8fd0\u884c\u540e\u7aef\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\">pm2 start ecosystem.config.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u4f60\u7684\u8f93\u51fa\u5c06\u4f1a\u662f\u4ee5\u4e0b\u5185\u5bb9\u7684\u67d0\u79cd\u53d8\u5316\uff1a<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>[PM2][WARN] Applications back-end not running, starting...\r\n[PM2] App [back-end] launched (1 instances)\r\n\u250c\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\r\n\u2502 id \u2502 name               \u2502 mode     \u2502 \u21ba    \u2502 status    \u2502 cpu      \u2502 memory   \u2502\r\n\u251c\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\r\n\u2502 2  \u2502 back-end           \u2502 fork     \u2502 0    \u2502 online    \u2502 0%       \u2502 24.0mb   \u2502\r\n\u2502 0  \u2502 front-end          \u2502 fork     \u2502 9    \u2502 online    \u2502 0%       \u2502 47.2mb   \u2502\r\n\u2514\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\r\n<\/code><\/pre>\n<p>\u4f60\u5c06\u4f7f\u7528curl\u6765\u8bc4\u4f30\u4f60\u65b0\u521b\u5efa\u7684API\u7aef\u70b9\u662f\u5426\u6b63\u786e\u5730\u8fd4\u56de\u4e00\u4e2a\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">curl<\/span> localhost:8080\/login\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u4f60\u5e94\u8be5\u770b\u5230\u4e0b\u9762\u7684\u8f93\u51fa\u7ed3\u679c\u3002<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>{\"token\":\"This is a secret token\"}\r\n<\/code><\/pre>\n<p>\u73b0\u5728\u4f60\u77e5\u9053\u4f60\u7684\u670d\u52a1\u5668\u767b\u5f55\u8def\u5f84\u6309\u9884\u671f\u8fd4\u56de\u4e86\u4ee4\u724c\u3002<\/p>\n<p>\u7136\u540e\uff0c\u60a8\u5c06\u4fee\u6539\u524d\u7aef\u767b\u5f55\u7ec4\u4ef6\u4ee5\u4f7f\u7528API\u3002\u5bfc\u822a\u81f3\u76f8\u5e94\u7684\u524d\u7aef\u6587\u4ef6\u5939\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token builtin class-name\">cd<\/span> <span class=\"token punctuation\">..<\/span>\r\n<\/li><li data-prefix=\"$\"><span class=\"token builtin class-name\">cd<\/span> front-end\/src\/components\/\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u6253\u5f00\u524d\u7aef\u7684Login.js\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> Login.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u6dfb\u52a0\u4e86\u7a81\u51fa\u663e\u793a\u7684\u884c\uff1a<\/p>\n<div>\u4f7f\u7528JavaScript\u7f16\u5199\u7684\u767b\u5f55\u7ec4\u4ef6\u4f4d\u4e8ejwt-storage-tutorial\/front-end\/src\/components\/Login.js\u6587\u4ef6\u4e2d\u3002<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> React<mark><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> useRef <span class=\"token punctuation\">}<\/span><\/mark> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <mark><span class=\"token keyword\">const<\/span> emailRef <span class=\"token operator\">=<\/span> <span class=\"token function\">useRef<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n  <mark><span class=\"token keyword\">const<\/span> passwordRef <span class=\"token operator\">=<\/span> <span class=\"token function\">useRef<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">'login-wrapper'<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>h1<span class=\"token operator\">&gt;<\/span>Login<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>form<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>Username<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>input type<span class=\"token operator\">=<\/span><span class=\"token string\">\"text\"<\/span> <mark>ref<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>emailRef<span class=\"token punctuation\">}<\/span><\/mark> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>Password<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>input type<span class=\"token operator\">=<\/span><span class=\"token string\">\"password\"<\/span> <mark>ref<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>passwordRef<span class=\"token punctuation\">}<\/span><\/mark> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>button type<span class=\"token operator\">=<\/span><span class=\"token string\">\"submit\"<\/span><span class=\"token operator\">&gt;<\/span>Submit<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>button<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>form<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>           \r\n<\/code><\/pre>\n<p>\u4f60\u53ef\u4ee5\u4f7f\u7528useRef\u94a9\u5b50\u6765\u8ddf\u8e2a\u7535\u5b50\u90ae\u4ef6\u548c\u5bc6\u7801\u8f93\u5165\u5b57\u6bb5\u7684\u503c\u3002\u5f53\u5728\u4e0euseRef\u94a9\u5b50\u7ed1\u5b9a\u7684\u8f93\u5165\u5b57\u6bb5\u4e2d\u8f93\u5165\u65f6\uff0c\u8f93\u5165\u7684\u503c\u5c06\u5728\u5f15\u7528\u4e2d\u66f4\u65b0\uff0c\u7136\u540e\u5728\u6309\u4e0b\u63d0\u4ea4\u6309\u94ae\u65f6\u5c06\u5176\u53d1\u9001\u5230\u540e\u7aef\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u6dfb\u52a0\u9ad8\u4eae\u663e\u793a\u7684\u4ee3\u7801\u884c\u4ee5\u521b\u5efahandleSubmit\u56de\u8c03\u51fd\u6570\uff0c\u4ee5\u5904\u7406\u8868\u5355\u4e2d\u6309\u4e0b\u63d0\u4ea4\u6309\u94ae\u7684\u60c5\u51b5\u3002<\/p>\n<div>jwt-storage-tutorial\/front-end\/src\/components\/Login.js \u7684\u4e2d\u6587\u7ffb\u8bd1: &#8220;\u767b\u5f55.js&#8221;\u3002\n<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> React<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> useRef <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<mark><span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">loginUser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">credentials<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n  <mark><span class=\"token keyword\">return<\/span> <span class=\"token function\">fetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'http:\/\/localhost:8080\/login'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark><span class=\"token literal-property property\">method<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'POST'<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n    <mark><span class=\"token literal-property property\">headers<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n      <mark><span class=\"token string-property property\">'Content-Type'<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'application\/json'<\/span><\/mark>\r\n    <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n    <mark><span class=\"token literal-property property\">body<\/span><span class=\"token operator\">:<\/span> <span class=\"token constant\">JSON<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">stringify<\/span><span class=\"token punctuation\">(<\/span>credentials<span class=\"token punctuation\">)<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">data<\/span> <span class=\"token operator\">=&gt;<\/span> data<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n<mark><span class=\"token punctuation\">}<\/span><\/mark>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> <span class=\"token punctuation\">(<\/span><mark><span class=\"token parameter\"><span class=\"token punctuation\">{<\/span> setToken <span class=\"token punctuation\">}<\/span><\/span><\/mark><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">const<\/span> emailRef <span class=\"token operator\">=<\/span> <span class=\"token function\">useRef<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token keyword\">const<\/span> passwordRef <span class=\"token operator\">=<\/span> <span class=\"token function\">useRef<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n  <mark><span class=\"token keyword\">const<\/span> <span class=\"token function-variable function\">handleSubmit<\/span> <span class=\"token operator\">=<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">e<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark>e<span class=\"token punctuation\">.<\/span><span class=\"token function\">preventDefault<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n    <mark><span class=\"token keyword\">const<\/span> token <span class=\"token operator\">=<\/span> <span class=\"token keyword\">await<\/span> <span class=\"token function\">loginUser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><\/mark>\r\n        <mark><span class=\"token literal-property property\">username<\/span><span class=\"token operator\">:<\/span> emailRef<span class=\"token punctuation\">.<\/span>current<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">,<\/span><\/mark>\r\n        <mark><span class=\"token literal-property property\">password<\/span><span class=\"token operator\">:<\/span> passwordRef<span class=\"token punctuation\">.<\/span>current<span class=\"token punctuation\">.<\/span>value<\/mark>\r\n    <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n    <mark><span class=\"token function\">setToken<\/span><span class=\"token punctuation\">(<\/span>token<span class=\"token punctuation\">)<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span><\/mark>\r\n\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">'login-wrapper'<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>h1<span class=\"token operator\">&gt;<\/span>Login<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>form <mark>onSubmit<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>handleSubmit<span class=\"token punctuation\">}<\/span><\/mark><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>Username<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>input type<span class=\"token operator\">=<\/span><span class=\"token string\">\"text\"<\/span> ref<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>emailRef<span class=\"token punctuation\">}<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>Password<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>input type<span class=\"token operator\">=<\/span><span class=\"token string\">\"password\"<\/span> ref<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>passwordRef<span class=\"token punctuation\">}<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>button type<span class=\"token operator\">=<\/span><span class=\"token string\">\"submit\"<\/span><span class=\"token operator\">&gt;<\/span>Submit<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>button<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>form<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n<\/code><\/pre>\n<p>\u5728handleSubmit\u5904\u7406\u7a0b\u5e8f\u51fd\u6570\u5185\u90e8\uff0c\u60a8\u8c03\u7528loginUser\u52a9\u624b\u51fd\u6570\u6765\u5411\u4e4b\u524d\u521b\u5efa\u7684API\u7684\u767b\u5f55\u8def\u7531\u53d1\u51fafetch\u8bf7\u6c42\u3002\u5728handleSubmit\u51fd\u6570\u4e2d\u5bf9\u4f20\u5165\u7684\u4e8b\u4ef6\u8c03\u7528preventDefault\u51fd\u6570\u610f\u5473\u7740\u4e0d\u6267\u884c\u63d0\u4ea4\u6309\u94ae\u7684\u9ed8\u8ba4\u5237\u65b0\u529f\u80fd\uff0c\u56e0\u6b64\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u53ef\u4ee5\u8c03\u7528\u767b\u5f55\u7aef\u70b9\u5e76\u5904\u7406\u7528\u6237\u767b\u5f55\u6240\u9700\u7684\u6b65\u9aa4\u3002\u5b83\u8fd8\u4f7f\u7528\u4f5c\u4e3a\u5c5e\u6027\u4f20\u9012\u7ed9Login\u7ec4\u4ef6\u7684setter\u6765\u8bbe\u7f6etoken\u72b6\u6001\u53d8\u91cf\u7684\u503c\u3002<\/p>\n<p>\u5b8c\u6210\u540e\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u5f53\u60a8\u5728\u6d4f\u89c8\u5668\u4e2d\u68c0\u67e5 Web \u5e94\u7528\u7a0b\u5e8f\u65f6\uff0c\u60a8\u73b0\u5728\u53ef\u4ee5\u4f7f\u7528\u4efb\u610f\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801\u8fdb\u884c\u767b\u5f55\u3002\u70b9\u51fb\u63d0\u4ea4\u6309\u94ae\uff0c\u5c06\u88ab\u91cd\u5b9a\u5411\u5230\u4e00\u4e2a\u5df2\u767b\u5f55\u7684\u9875\u9762\u3002\u5982\u679c\u60a8\u5237\u65b0\u9875\u9762\uff0c\u60a8\u7684 React \u5e94\u7528\u7a0b\u5e8f\u5c06\u4e22\u5931\u4ee4\u724c\uff0c\u5e76\u4e14\u60a8\u5c06\u88ab\u6ce8\u9500\u3002<\/p>\n<p>\u5728\u63a5\u4e0b\u6765\u7684\u6b65\u9aa4\u4e2d\uff0c\u60a8\u5c06\u4f7f\u7528\u6d4f\u89c8\u5668\u5b58\u50a8\u673a\u5236\u6765\u4fdd\u5b58\u5728\u524d\u7aef\u5e94\u7528\u7a0b\u5e8f\u4e2d\u6536\u5230\u7684\u4ee4\u724c\u3002<\/p>\n<h2>\u6b65\u9aa45 \u2014 \u4f7f\u7528\u6d4f\u89c8\u5668\u5b58\u50a8\u6765\u50a8\u5b58\u4ee4\u724c<\/h2>\n<p>\u5982\u679c\u7528\u6237\u80fd\u591f\u5728\u6d4f\u89c8\u5668\u4f1a\u8bdd\u548c\u9875\u9762\u5237\u65b0\u4e4b\u95f4\u4fdd\u6301\u767b\u5f55\u72b6\u6001\uff0c\u5c06\u6709\u52a9\u4e8e\u63d0\u9ad8\u7528\u6237\u4f53\u9a8c\u3002\u5728\u8fd9\u4e2a\u6b65\u9aa4\u4e2d\uff0c\u60a8\u5c06\u4f7f\u7528Window.localStorage\u5c5e\u6027\u6765\u5b58\u50a8\u8ba4\u8bc1\u4ee4\u724c\uff0c\u4ee5\u5b9e\u73b0\u6301\u4e45\u7684\u7528\u6237\u4f1a\u8bdd\uff0c\u5373\u4f7f\u7528\u6237\u5173\u95ed\u6d4f\u89c8\u5668\u6216\u5237\u65b0\u7f51\u9875\u4e5f\u4e0d\u4f1a\u4e22\u5931\u3002\u5bf9\u4e8e\u73b0\u4ee3Web\u5e94\u7528\u7a0b\u5e8f\u800c\u8a00\uff0c\u6301\u7eed\u7684\u7528\u6237\u4f1a\u8bdd\u53ef\u4ee5\u51cf\u5c11\u5e94\u7528\u7a0b\u5e8f\u5904\u7406\u7684\u7f51\u7edc\u6d41\u91cf\uff0c\u56e0\u4e3a\u7528\u6237\u4e0d\u9700\u8981\u9891\u7e41\u4f7f\u7528\u76f8\u540c\u7f51\u7ad9\u7684\u767b\u5f55\u51ed\u636e\u3002<\/p>\n<p>\u6d4f\u89c8\u5668\u5b58\u50a8\u5305\u62ec\u4e24\u79cd\u4e0d\u540c\u4f46\u76f8\u4f3c\u7684\u5b58\u50a8\u7c7b\u578b\uff1a\u672c\u5730\u5b58\u50a8\u548c\u4f1a\u8bdd\u5b58\u50a8\u3002\u7b80\u800c\u8a00\u4e4b\uff0c\u4f1a\u8bdd\u5b58\u50a8\u5728\u6807\u7b7e\u4f1a\u8bdd\u95f4\u4fdd\u7559\u6570\u636e\uff0c\u800c\u672c\u5730\u5b58\u50a8\u5728\u6807\u7b7e\u548c\u6d4f\u89c8\u5668\u4f1a\u8bdd\u95f4\u4fdd\u7559\u6570\u636e\u3002\u8981\u4f7f\u7528\u6d4f\u89c8\u5668\u5b58\u50a8\u5b58\u50a8\u60a8\u7684\u4ee4\u724c\uff0c\u60a8\u5c06\u4f7f\u7528\u672c\u5730\u5b58\u50a8\u3002<\/p>\n<p>\u6253\u5f00\u4f60\u7684\u524d\u7aef\u5e94\u7528\u7684App.js\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> \/app\/jwt-storage-tutorial\/front-end\/src\/App.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5f00\u59cb\u6574\u5408\u6d4f\u89c8\u5668\u5b58\u50a8\u65f6\uff0c\u8bf7\u6dfb\u52a0\u4e0b\u9762\u7a81\u51fa\u663e\u793a\u7684\u4ee3\u7801\u884c\uff0c\u5176\u4e2d\u5b9a\u4e49\u4e86\u4e24\u4e2a\u8f85\u52a9\u51fd\u6570\uff08setToken \u548c getToken\uff09\uff0c\u5e76\u4f7f\u7528\u65b0\u5b9e\u73b0\u7684\u51fd\u6570\u6765\u83b7\u53d6 token \u53d8\u91cf\uff1a<\/p>\n<div>\u8bf7\u5c06\u4ee5\u4e0b\u5185\u5bb9\u7528\u4e2d\u6587\u8fdb\u884c\u91cd\u8ff0\uff0c\u4ec5\u9700\u8981\u4e00\u4e2a\u7248\u672c\uff1a<br \/>\njwt-storage-tutorial\/front-end\/src\/App.js<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useState <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> BrowserRouter<span class=\"token punctuation\">,<\/span> Route<span class=\"token punctuation\">,<\/span> Switch <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> SubscriberFeed <span class=\"token keyword\">from<\/span> <span class=\"token string\">\".\/components\/SubscriberFeed\"<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> Login <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/components\/Login'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<mark><span class=\"token keyword\">function<\/span> <span class=\"token function\">setToken<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">userToken<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n  <mark>localStorage<span class=\"token punctuation\">.<\/span><span class=\"token function\">setItem<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'token'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token constant\">JSON<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">stringify<\/span><span class=\"token punctuation\">(<\/span>userToken<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n  <mark>window<span class=\"token punctuation\">.<\/span>location<span class=\"token punctuation\">.<\/span><span class=\"token function\">reload<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n<mark><span class=\"token punctuation\">}<\/span><\/mark>\r\n\r\n<mark><span class=\"token keyword\">function<\/span> <span class=\"token function\">getToken<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n  <mark><span class=\"token keyword\">const<\/span> tokenString <span class=\"token operator\">=<\/span> localStorage<span class=\"token punctuation\">.<\/span><span class=\"token function\">getItem<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'token'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n  <mark><span class=\"token keyword\">const<\/span> userToken <span class=\"token operator\">=<\/span> <span class=\"token constant\">JSON<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">parse<\/span><span class=\"token punctuation\">(<\/span>tokenString<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n  <mark><span class=\"token keyword\">return<\/span> userToken<span class=\"token operator\">?.<\/span>token<\/mark>\r\n<mark><span class=\"token punctuation\">}<\/span><\/mark>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <mark><span class=\"token keyword\">let<\/span> token <span class=\"token operator\">=<\/span> <span class=\"token function\">getToken<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n\r\n  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>token<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token keyword\">return<\/span> <span class=\"token operator\">&lt;<\/span>Login setToken<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>setToken<span class=\"token punctuation\">}<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">}<\/span>\r\n\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App wrapper\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>h1 className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token constant\">JWT<\/span><span class=\"token operator\">-<\/span>Storage<span class=\"token operator\">-<\/span>Tutorial Application\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/subscriber-feed\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n            <span class=\"token operator\">&lt;<\/span>SubscriberFeed <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>  \r\n<\/code><\/pre>\n<p>\u60a8\u521b\u5efa\u4e24\u4e2a\u8f85\u52a9\u51fd\u6570\uff1asetToken\u548cgetToken\u3002\u5728setToken\u51fd\u6570\u5185\u90e8\uff0c\u60a8\u4f7f\u7528localStorage\u7684setItem\u51fd\u6570\u5c06\u7528\u6237\u8f93\u5165\u53c2\u6570userToken\u6620\u5c04\u5230\u540d\u4e3atoken\u7684\u952e\u3002\u60a8\u8fd8\u5c06\u4f7f\u7528window.location\u7684reload\u51fd\u6570\u5237\u65b0\u9875\u9762\uff0c\u4ee5\u4fbf\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u53ef\u4ee5\u5728\u6d4f\u89c8\u5668\u5b58\u50a8\u4e2d\u627e\u5230\u65b0\u8bbe\u7f6e\u7684token\uff0c\u5e76\u91cd\u65b0\u6e32\u67d3\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<p>\u5728getToken\u5185\u90e8\uff0c\u4f60\u5c06\u4f7f\u7528localStorage\u7684getItem\u51fd\u6570\u6765\u68c0\u67e5\u662f\u5426\u5b58\u5728token\u952e\u7684\u4efb\u4f55\u503c\uff0c\u7136\u540e\u5c06\u5176\u8fd4\u56de\u3002\u4f60\u5c06\u66ff\u6362App()\u51fd\u6570\u4e2d\u7684\u5b9a\u4e49\u53d8\u91cf\uff0c\u4ee5\u4f7f\u7528getToken\u51fd\u6570\u3002<\/p>\n<p>\u6bcf\u6b21\u7528\u6237\u8bbf\u95ee\u60a8\u7684\u7f51\u7ad9\u65f6\uff0c\u524d\u7aef\u5c06\u68c0\u67e5\u6d4f\u89c8\u5668\u5b58\u50a8\u4e2d\u662f\u5426\u5b58\u5728\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\uff0c\u5e76\u5c1d\u8bd5\u4f7f\u7528\u5df2\u5b58\u5728\u7684\u4ee4\u724c\u9a8c\u8bc1\u7528\u6237\uff0c\u800c\u4e0d\u662f\u8981\u6c42\u4ed6\u4eec\u767b\u5f55\u3002<\/p>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\uff0c\u7136\u540e\u5237\u65b0\u5e94\u7528\u7a0b\u5e8f\u3002\u60a8\u5e94\u8be5\u80fd\u591f\u73b0\u5728\u767b\u5f55\u5e94\u7528\u7a0b\u5e8f\uff0c\u5237\u65b0\u7f51\u9875\uff0c\u800c\u65e0\u9700\u518d\u6b21\u767b\u5f55\u3002<\/p>\n<p>\u5728\u8fd9\u4e00\u6b65\u9aa4\u4e2d\uff0c\u60a8\u4f7f\u7528\u6d4f\u89c8\u5668\u5b58\u50a8\u5b9e\u73b0\u4e86\u4ee4\u724c\u6301\u4e45\u5316\u3002\u60a8\u5c06\u5728\u4e0b\u4e00\u90e8\u5206\u4e2d\u5229\u7528\u57fa\u4e8e\u6d4f\u89c8\u5668\u5b58\u50a8\u7684\u4ee4\u724c\u8ba4\u8bc1\u7cfb\u7edf\u3002<\/p>\n<h2>\u7b2c\u516d\u6b65 &#8211; \u5229\u7528XSS\u653b\u51fb\u7a83\u53d6\u6d4f\u89c8\u5668\u5b58\u50a8<\/h2>\n<p>\u5728\u8fd9\u4e00\u6b65\u4e2d\uff0c\u60a8\u5c06\u5bf9\u5f53\u524d\u5e94\u7528\u7a0b\u5e8f\u6267\u884c\u4e00\u6b21\u5206\u9636\u6bb5\u7684\u8de8\u7ad9\u811a\u672c\u653b\u51fb\uff08\u4e5f\u79f0\u4e3aXSS\u653b\u51fb\uff09\uff0c\u8be5\u653b\u51fb\u5c06\u5c55\u793a\u5728\u4f7f\u7528\u6d4f\u89c8\u5668\u5b58\u50a8\u6765\u6301\u4e45\u4fdd\u5b58\u5bc6\u94a5\u4fe1\u606f\u65f6\u5b58\u5728\u7684\u5b89\u5168\u6f0f\u6d1e\u3002\u8fd9\u79cd\u653b\u51fb\u5c06\u4ee5URL\u94fe\u63a5\u7684\u5f62\u5f0f\u5448\u73b0\uff0c\u5f53\u88ab\u70b9\u51fb\u65f6\uff0c\u4f1a\u5c06\u53d7\u5bb3\u8005\u5f15\u5bfc\u5230\u60a8\u7684\u7f51\u7edc\u5e94\u7528\u7a0b\u5e8f\uff0c\u5e76\u5411\u5e94\u7528\u7a0b\u5e8f\u6ce8\u5165\u7ecf\u8fc7\u7cbe\u5fc3\u8bbe\u8ba1\u7684\u4ee3\u7801\u3002\u8fd9\u79cd\u6ce8\u5165\u53ef\u80fd\u4f1a\u8bf1\u4f7f\u7528\u6237\u4e0e\u4e4b\u4e92\u52a8\uff0c\u4ece\u800c\u5141\u8bb8\u6076\u610f\u4ee3\u7406\u4eba\u7a83\u53d6\u53d7\u5bb3\u8005\u6d4f\u89c8\u5668\u4e0a\u672c\u5730\u5b58\u50a8\u7684\u5185\u5bb9\u3002<\/p>\n<p>\u8de8\u7ad9\u811a\u672c\u653b\u51fb\u662f\u73b0\u4ee3\u6700\u5e38\u89c1\u7684\u7f51\u7edc\u653b\u51fb\u4e4b\u4e00\u3002\u653b\u51fb\u8005\u901a\u5e38\u5c06\u6076\u610f\u811a\u672c\u6ce8\u5165\u6d4f\u89c8\u5668\uff0c\u4ee5\u5728\u53ef\u4fe1\u73af\u5883\u4e2d\u5b9e\u73b0\u4ee3\u7801\u6267\u884c\u3002\u653b\u51fb\u8005\u7ecf\u5e38\u5229\u7528\u7f51\u7edc\u9493\u9c7c\u6280\u672f\uff0c\u901a\u8fc7\u4e0e\u6076\u610f\u6784\u9020\u7684\u94fe\u63a5\uff08\u5982\u5783\u573e\u90ae\u4ef6\u4e2d\u7684\u94fe\u63a5\uff09\u8fdb\u884c\u4ea4\u4e92\uff0c\u8bf1\u4f7f\u7528\u6237\u727a\u7272\u5176\u6d4f\u89c8\u5668\u5b58\u50a8\u7684\u5185\u5bb9\u3002<\/p>\n<p>XSS\u653b\u51fb\u5bf9\u4e8e\u8bd5\u56fe\u7a83\u53d6\u6beb\u65e0\u9632\u5907\u7684\u53d7\u5bb3\u8005\u6d4f\u89c8\u5668\u5b58\u50a8\u5185\u5bb9\u7684\u653b\u51fb\u8005\u6765\u8bf4\u7279\u522b\u611f\u5174\u8da3\uff0c\u56e0\u4e3a\u4e0e\u8be5\u57df\u5173\u8054\u7684\u4efb\u4f55\u6587\u6863\u4e0a\u8fd0\u884c\u7684JavaScript\u4ee3\u7801\u5b8c\u5168\u53ef\u4ee5\u8bbf\u95ee\u8be5\u57df\u7684\u6d4f\u89c8\u5668\u5b58\u50a8\u3002\u5982\u679c\u653b\u51fb\u8005\u80fd\u591f\u5728\u7528\u6237\u6d4f\u89c8\u5668\u4e0a\u6267\u884c\u7279\u5b9a\u7f51\u9875\u6587\u6863\u7684JavaScript\u4ee3\u7801\uff0c\u5219\u53ef\u4ee5\u7a83\u53d6\u7528\u6237\u6d4f\u89c8\u5668\u5b58\u50a8\uff08\u5305\u62ec\u672c\u5730\u548c\u4f1a\u8bdd\uff09\u4e2d\u4e0e\u8be5\u6587\u6863\u76f8\u5173\u8054\u7684\u7f51\u57df\u7684\u5185\u5bb9\u3002<\/p>\n<p>\u4e3a\u4e86\u6559\u5b66\u76ee\u7684\uff0c\u4f60\u4f1a\u6709\u610f\u5730\u8ba9\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u5bb9\u6613\u53d7\u5230\u8de8\u7ad9\u811a\u672c\u653b\u51fb\uff0c\u901a\u8fc7\u521b\u5efa\u4e00\u4e2a\u540d\u4e3aXSSHelper\u7684\u7ec4\u4ef6\uff0c\u53ef\u4ee5\u901a\u8fc7URL\u67e5\u8be2\u53c2\u6570\u6ce8\u5165\u4ee3\u7801\u8fdb\u5165\u5176\u4e2d\u3002\u7136\u540e\uff0c\u4f60\u5c06\u901a\u8fc7\u6784\u5efa\u4e00\u4e2a\u6076\u610f\u7684URL\u6765\u5229\u7528\u8fd9\u4e2a\u6f0f\u6d1e\u3002\u5f53\u7528\u6237\u5728\u6d4f\u89c8\u5668\u4e2d\u5bfc\u822a\u5230\u8be5URL\u5e76\u70b9\u51fb\u88ab\u6ce8\u5165\u5230\u7f51\u9875\u4e2d\u7684\u53ef\u7591\u94fe\u63a5\u65f6\uff0c\u8be5\u6076\u610f\u7684URL\u5c06\u8bbf\u95ee\u5e76\u66b4\u9732\u5df2\u767b\u5f55\u7528\u6237\u672c\u5730\u5b58\u50a8\u4e2d\u7684\u5185\u5bb9\u3002<\/p>\n<p>\u5728\u524d\u7aef\u5e94\u7528\u7a0b\u5e8f\u7684\u7ec4\u4ef6\u76ee\u5f55\u4e2d\u6253\u5f00\u4e00\u4e2a\u540d\u4e3aXSSHelper.js\u7684\u65b0\u7ec4\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> \/app\/jwt-storage-tutorial\/front-end\/src\/components\/XSSHelper.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5c06\u4ee5\u4e0b\u4ee3\u7801\u6dfb\u52a0\u5230\u65b0\u6587\u4ef6\u4e2d\u3002<\/p>\n<div>\/src\/components\/XSSHelper.js \u7684\u4e2d\u6587\u539f\u751f\u8f49\u8ff0\u5982\u4e0b\uff1a<br \/>\n\/src\/components\/XSSHelper.js \u7ec4\u4ef6<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> React <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useLocation <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">props<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">const<\/span> search <span class=\"token operator\">=<\/span> <span class=\"token function\">useLocation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>search<span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token keyword\">const<\/span> code <span class=\"token operator\">=<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">URLSearchParams<\/span><span class=\"token punctuation\">(<\/span>search<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'code'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>h2<span class=\"token operator\">&gt;<\/span><span class=\"token constant\">XSS<\/span> Helper Active<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h2<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n<\/code><\/pre>\n<p>\u60a8\u521b\u5efa\u4e86\u4e00\u4e2a\u65b0\u7684\u529f\u80fd\u7ec4\u4ef6\uff0c\u8be5\u7ec4\u4ef6\u5bfc\u5165\u4e86useLocation\u94a9\u5b50\uff0c\u5e76\u901a\u8fc7useLocation\u94a9\u5b50\u7684search\u5c5e\u6027\u8bbf\u95ee\u4e86\u4ee3\u7801\u67e5\u8be2\u53c2\u6570\u3002\u60a8\u8fd4\u56de\u4e00\u4e2a\u5305\u542b\u6d88\u606f\u7684&lt;h2&gt;\u6807\u7b7e\uff0c\u4ee5\u8bf4\u660eXSSHelper\u7ec4\u4ef6\u662f\u6d3b\u52a8\u7684\u3002<\/p>\n<p>URLSearchParams\u8fd9\u4e2aJavaScript\u51fd\u6570\u63d0\u4f9b\u4e86\u4e00\u4e9b\u8f85\u52a9\u65b9\u6cd5\uff0c\u6bd4\u5982\u7528\u4e8e\u4e0e\u641c\u7d22\u5b57\u7b26\u4e32\u8fdb\u884c\u4ea4\u4e92\u7684\u83b7\u53d6\u5668\u3002<\/p>\n<p>\u73b0\u5728\u5c06\u7740\u91cd\u6807\u8bb0\u7684\u884c\u6dfb\u52a0\u5230\u4ee3\u7801\u4e2d\uff0c\u4ee5\u5f15\u5165\u5e76\u4f7f\u7528 useEffect \u94a9\u5b50\u6765\u8bb0\u5f55\u67e5\u8be2\u53c2\u6570\u7684\u503c\u3002<\/p>\n<div>\/src\/components\/XSSHelper.js \u7ec4\u4ef6<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> React<mark><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> useEffect <span class=\"token punctuation\">}<\/span><\/mark> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useLocation <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">props<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">const<\/span> search <span class=\"token operator\">=<\/span> <span class=\"token function\">useLocation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>search<span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token keyword\">const<\/span> code <span class=\"token operator\">=<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">URLSearchParams<\/span><span class=\"token punctuation\">(<\/span>search<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'code'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n  <mark><span class=\"token function\">useEffect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark>console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span>code<span class=\"token punctuation\">)<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>h2<span class=\"token operator\">&gt;<\/span><span class=\"token constant\">XSS<\/span> Helper Active<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h2<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n<\/code><\/pre>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u5f53\u7528\u6237\u5bfc\u822a\u5230\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u7684 xss-helper \u8def\u7531\u65f6\uff0c\u4f60\u5c06\u4fee\u6539\u4f60\u7684 App.js \u6587\u4ef6\u4ee5\u8fd4\u56de\u7ec4\u4ef6\u3002<\/p>\n<p>\u6253\u5f00App.js\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> \/app\/jwt-storage-tutorial\/front-end\/src\/App.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5c06\u4e0b\u9762\u7684\u4ee3\u7801\u6dfb\u52a0\u5230import\u90e8\u5206\uff0c\u5c06XSSHelper\u7ec4\u4ef6\u4f5c\u4e3a\u4e00\u4e2a\u8def\u7531\u6dfb\u52a0\u8fdb\u53bb\uff1a<\/p>\n<div>jwt-storage-tutorial\/front-end\/src\/App.js\u7684\u542b\u4e49\u662f\u4ec0\u4e48\uff1f<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useState <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> BrowserRouter<span class=\"token punctuation\">,<\/span> Route<span class=\"token punctuation\">,<\/span> Switch <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> SubscriberFeed <span class=\"token keyword\">from<\/span> <span class=\"token string\">\".\/components\/SubscriberFeed\"<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> Login <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/components\/Login'<\/span><span class=\"token punctuation\">;<\/span>\r\n<mark><span class=\"token keyword\">import<\/span> XSSHelper <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/components\/XSSHelper'<\/span><\/mark>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">setToken<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">userToken<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  localStorage<span class=\"token punctuation\">.<\/span><span class=\"token function\">setItem<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'token'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token constant\">JSON<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">stringify<\/span><span class=\"token punctuation\">(<\/span>userToken<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n  window<span class=\"token punctuation\">.<\/span>location<span class=\"token punctuation\">.<\/span><span class=\"token function\">reload<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">getToken<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">const<\/span> tokenString <span class=\"token operator\">=<\/span> localStorage<span class=\"token punctuation\">.<\/span><span class=\"token function\">getItem<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'token'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token keyword\">const<\/span> userToken <span class=\"token operator\">=<\/span> <span class=\"token constant\">JSON<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">parse<\/span><span class=\"token punctuation\">(<\/span>tokenString<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token keyword\">return<\/span> userToken<span class=\"token operator\">?.<\/span>token\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">let<\/span> token <span class=\"token operator\">=<\/span> <span class=\"token function\">getToken<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\n  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>token<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token keyword\">return<\/span> <span class=\"token operator\">&lt;<\/span>Login setToken<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>setToken<span class=\"token punctuation\">}<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">}<\/span>\r\n\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App wrapper\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>h1 className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token constant\">JWT<\/span><span class=\"token operator\">-<\/span>Storage<span class=\"token operator\">-<\/span>Tutorial Application\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/subscriber-feed\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n            <span class=\"token operator\">&lt;<\/span>SubscriberFeed <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span>\r\n          <mark><span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/xss-helper\"<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n            <mark><span class=\"token operator\">&lt;<\/span>XSSHelper <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n          <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span><\/mark>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>  \r\n<\/code><\/pre>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u8bf7\u5728\u6d4f\u89c8\u5668\u4e2d\u5bfc\u822a\u81f3localhost:3000\/xss-helper?code=&#8217;\u5728\u6b64\u5904\u63d2\u5165\u4ee3\u7801&#8217;\u3002\u786e\u4fdd\u60a8\u5df2\u767b\u5f55\u8be5\u5e94\u7528\u7a0b\u5e8f\uff0c\u5426\u5219\u60a8\u5c06\u65e0\u6cd5\u8bbf\u95eeXSSHelper\u7ec4\u4ef6\u3002<\/p>\n<p>\u70b9\u51fb\u5de6\u952e\u5e76\u6309\u4e0b\u201c\u68c0\u67e5\u201d\u6309\u94ae\u3002\u7136\u540e\u5bfc\u822a\u5230\u63a7\u5236\u53f0\u90e8\u5206\u3002\u5728\u63a7\u5236\u53f0\u65e5\u5fd7\u4e2d\uff0c\u4f60\u4f1a\u770b\u5230\u201c\u5728\u6b64\u5904\u63d2\u5165\u4ee3\u7801\u201d\u3002<\/p>\n<div>\n                            <img decoding=\"async\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/6564666ea4b2f92e6c7266b0\/254-0.png\" class='post-images' alt=\"Screencapture of the XSS Helper page with the URL query parameter passing to show the  message\" title=\"\">\n                        <\/div>\n<p>\u4f60\u73b0\u5728\u77e5\u9053\u4e86\u4f60\u53ef\u4ee5\u5c06URL\u67e5\u8be2\u53c2\u6570\u4f20\u9012\u7ed9\u4f60\u7684\u7ec4\u4ef6\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u60a8\u5c06\u4f7f\u7528dangerouslySetInnerHTML\u5c5e\u6027\u5728\u7f51\u9875\u6587\u6863\u4e0a\u8bbe\u7f6e\u4f20\u9012\u5230\u7ec4\u4ef6\u4e2d\u7684\u67e5\u8be2\u53c2\u6570\u7684\u503c\u3002\u8be5\u7ec4\u4ef6\u4f1a\u5c06\u4ee3\u7801URL\u67e5\u8be2\u53c2\u6570\u7684\u503c\u6ce8\u5165\u5230\u7f51\u9875\u4e0a\u7684\u4e00\u4e2adiv\u7ec4\u4ef6\u4e2d\u3002<\/p>\n<div class=\"post-conf-warning\">\n<p class=\"post-warning\">\n<p class=\"post-conf-desc\">Warning<\/p>\n<div>\u8b66\u544a\uff1a\u5728\u751f\u4ea7\u73af\u5883\u4e2d\u4f7f\u7528dangerouslySetInnerHTML\u5c5e\u6027\u53ef\u80fd\u4f7f\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u5bb9\u6613\u53d7\u5230XSS\u653b\u51fb\u7684\u5a01\u80c1\u3002<\/div>\n<\/div>\n<p>\u518d\u6b21\u6253\u5f00XSSHelper\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> XSSHelper.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u6dfb\u52a0\u4ee5\u4e0b\u7ebf\u6761\uff1a<\/p>\n<div>\u6e90\u7801\/components\/XSSHelper.js<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> React<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span>useEffect<span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useLocation <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">props<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">const<\/span> search <span class=\"token operator\">=<\/span> <span class=\"token function\">useLocation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span>search<span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token keyword\">const<\/span> code <span class=\"token operator\">=<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">URLSearchParams<\/span><span class=\"token punctuation\">(<\/span>search<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'code'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n  <span class=\"token function\">useEffect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n    console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span>code<span class=\"token punctuation\">)<\/span>\r\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n      <span class=\"token operator\">&lt;<\/span>h2<span class=\"token operator\">&gt;<\/span><span class=\"token constant\">XSS<\/span> Helper Active<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h2<span class=\"token operator\">&gt;<\/span>\r\n      <mark><span class=\"token operator\">&lt;<\/span>div dangerouslySetInnerHTML<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span><span class=\"token punctuation\">{<\/span><span class=\"token literal-property property\">__html<\/span><span class=\"token operator\">:<\/span> code<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">}<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n    <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n<\/code><\/pre>\n<p>\u4e3a\u4e86\u907f\u514d\u5728\u4f7f\u7528React\u7247\u6bb5\u65f6\u4ea7\u751f\u591a\u4e2a\u788e\u7247\u5316\u7684JSX\u8fd4\u56de\u7ed3\u679c\uff08\u4ece\u8bed\u6cd5\u4e0a\u6765\u8bf4\u662f\u975e\u6cd5\u7684\uff09\uff0c\u4f60\u53ef\u4ee5\u628a\u8981\u8fd4\u56de\u7684\u5143\u7d20\u7528\u7a7a\u7684JSX\u6807\u7b7e\uff08&lt;&gt; &#8230; &lt;\/&gt;\uff09\u5305\u88f9\u8d77\u6765\u3002<\/p>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u73b0\u5728\u4f60\u53ef\u4ee5\u5c06\u6076\u610f\u6784\u5efa\u7684\u4ee3\u7801\u6ce8\u5165\u5230\u4f60\u7684\u7ec4\u4ef6\u4e2d\uff0c\u5728\u7f51\u9875\u4e0a\u6267\u884c\u4ee3\u7801\u3002<\/p>\n<p>\u4f60\u77e5\u9053\u5c06\u53d1\u9001\u5230xss-helper\u8def\u7531\u7684\u4ee3\u7801\u67e5\u8be2\u53c2\u6570\u7684\u503c\u5c06\u76f4\u63a5\u5d4c\u5165\u5230\u4f60\u7684\u5e94\u7528\u7a0b\u5e8f\u6587\u6863\u4e2d\u3002\u4f60\u53ef\u4ee5\u5c06\u4ee3\u7801\u67e5\u8be2\u53c2\u6570\u7684\u503c\u8bbe\u7f6e\u4e3a\u4e00\u4e2a\u5e26\u6709&lt;a&gt;\u6807\u7b7e\u7684\u94fe\u63a5\uff0c\u4f7f\u7528href\u5c5e\u6027\u5c06\u81ea\u5b9a\u4e49\u7684JavaScript\u4ee3\u7801\u76f4\u63a5\u4f20\u9012\u5230\u6d4f\u89c8\u5668\u3002<\/p>\n<p>\u5728\u6d4f\u89c8\u5668\u4e2d\u8f93\u5165\u4ee5\u4e0bURL\u8fdb\u884c\u5bfc\u822a\uff1a<\/p>\n<pre class=\"post-pre\"><code>localhost:3000\/xss-helper?code=&lt;a href=\"javascript:alert(`You have been pwned`);\"&gt;Click Me!&lt;\/a&gt;\r\n<\/code><\/pre>\n<p>\u5728\u4e0a\u8ff0URL\u4e2d\uff0c\u60a8\u53ef\u4ee5\u521b\u5efa\u4e00\u4e2a\u67e5\u8be2\u53c2\u6570\u7684XSS\u8f7d\u8377\uff0c\u4ee5\u4e00\u4e2a\u540d\u4e3a\u201c\u70b9\u51fb\u6211\uff01\u201d \u7684\u94fe\u63a5\u5f62\u5f0f\u663e\u793a\u5728\u7f51\u9875\u4e0a\u3002\u5f53\u7528\u6237\u70b9\u51fb\u94fe\u63a5\u65f6\uff0c\u94fe\u63a5\u4f1a\u544a\u8bc9\u6d4f\u89c8\u5668\u6267\u884c\u60a8\u7f16\u5199\u7684JavaScript\u4ee3\u7801\u3002\u8be5\u4ee3\u7801\u4f7f\u7528alert\u51fd\u6570\u521b\u5efa\u4e00\u4e2a\u5f39\u51fa\u7a97\u53e3\uff0c\u663e\u793a\u6d88\u606f\u201c\u60a8\u5df2\u88ab\u9ed1\u5ba2\u5165\u4fb5\u201d\u3002<\/p>\n<div>\n                            <img decoding=\"async\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/6564666ea4b2f92e6c7266b0\/270-0.png\" class='post-images' alt=\"Screencapture of a successful XSS attack that displays the \"You have been pwned\" pop-up\" title=\"\">\n                        <\/div>\n<p>\u63a5\u4e0b\u6765\uff0c\u5728\u60a8\u7684\u6d4f\u89c8\u5668\u4e2d\u8f93\u5165\u4ee5\u4e0b\u7f51\u5740\uff1a<\/p>\n<pre class=\"post-pre\"><code>localhost:3000\/xss-helper?code=&lt;a href=\"javascript:alert(`Your token object is ${localStorage.getItem('token')}. It has been sent to a malicious server &gt;:)`);\"&gt;Click Me!&lt;\/a&gt;\r\n<\/code><\/pre>\n<p>\u5bf9\u4e8e\u8fd9\u4e2a\u9875\u9762\u6765\u8bf4\uff0c\u901a\u8fc7URL\u67e5\u8be2\u53c2\u6570\u811a\u672c\u6ce8\u5165\uff0c\u653b\u51fb\u8005\u53ef\u4ee5\u8bbf\u95ee\u6d4f\u89c8\u5668\u5b58\u50a8\u5185\u5bb9\uff0c\u5e76\u4f7f\u7528JavaScript\u4ee3\u7801\u8bfb\u53d6localStorage\u4e2d\u7684\u4ee4\u724c\u503c\u3002<\/p>\n<p>\u53ea\u6709\u5728\u767b\u5f55\u5e94\u7528\u7a0b\u5e8f\u540e\uff0c\u4ee4\u724c\u624d\u4f1a\u5b58\u5728\uff0c\u8fd9\u6837\u60a8\u6076\u610f\u6784\u5efa\u7684URL\u624d\u80fd\u663e\u793a\u672c\u5730\u5b58\u50a8\u4e2d\u5b58\u50a8\u7684\u4ee4\u724c\u3002\u5f53\u60a8\u70b9\u51fb\u7f51\u9875\u4e0a\u7684&#8221;\u70b9\u6211\uff01&#8221;\u94fe\u63a5\u65f6\uff0c\u60a8\u5c06\u6536\u5230\u4e00\u4e2a\u5f39\u51fa\u6d88\u606f\uff0c\u8868\u793a\u60a8\u7684\u4ee4\u724c\u5df2\u88ab\u7a83\u53d6\u3002<\/p>\n<div>\n                            <img decoding=\"async\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/6564666ea4b2f92e6c7266b0\/275-0.png\" class='post-images' alt=\"Screencapture of a successful XSS attack for stealing the contents of local storage with a pop-up message informing the user of a stolen token\" title=\"\">\n                        <\/div>\n<p>\u5728\u8fd9\u4e00\u6b65\u4e2d\uff0c\u60a8\u4f7f\u7528\u4e86\u4f17\u591a\u653b\u51fb\u5411\u91cf\u4e4b\u4e00\u6765\u5b9e\u73b0\u4ee3\u7801\u6267\u884c\u3002\u6076\u610f\u653b\u51fb\u8005\u5229\u7528\u4e00\u4e2a\u6beb\u4e0d\u77e5\u60c5\u7684\u7528\u6237\u7684\u8ba4\u8bc1\u4ee4\u724c\uff0c\u53ef\u4ee5\u5192\u5145\u7528\u6237\u8fdb\u5165\u60a8\u7684\u7f51\u7edc\u5e94\u7528\u7a0b\u5e8f\uff0c\u4ee5\u8bbf\u95ee\u7279\u6743\u7ad9\u70b9\u8d44\u6e90\u3002\u901a\u8fc7\u8fd9\u4e9b\u6d4b\u8bd5\uff0c\u60a8\u73b0\u5728\u77e5\u9053\u5c06\u8bf8\u5982\u8ba4\u8bc1\u4ee4\u724c\u4e4b\u7c7b\u7684\u79d8\u5bc6\u4fe1\u606f\u5b58\u50a8\u5728\u6d4f\u89c8\u5668\u5b58\u50a8\u4e2d\u662f\u4e00\u79cd\u4e0d\u5b89\u5168\u7684\u505a\u6cd5\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u60a8\u5c06\u4f7f\u7528\u4e00\u79cd\u66ff\u4ee3\u65b9\u6cd5\u6765\u5b58\u50a8\u673a\u5bc6\u4fe1\u606f\uff0c\u8be5\u65b9\u6cd5\u5c06\u65e0\u6cd5\u88ab\u8fd0\u884c\u5728\u6587\u6863\u4e0a\u7684\u811a\u672c\u8bbf\u95ee\uff0c\u5e76\u4e14\u5bf9\u4e8e\u8fd9\u79cd\u7c7b\u578b\u7684\u8de8\u7ad9\u811a\u672c\u653b\u51fb\u662f\u514d\u75ab\u7684\u3002<\/p>\n<h2>\u7b2c\u4e03\u6b65 &#8211; \u4f7f\u7528\u4ec5\u9650HTTP\u7684Cookie\u6765\u51cf\u8f7b\u6d4f\u89c8\u5668\u5b58\u50a8XSS\u6f0f\u6d1e\u7684\u98ce\u9669\u3002<\/h2>\n<p>\u5728\u8fd9\u4e2a\u6b65\u9aa4\u4e2d\uff0c\u60a8\u5c06\u4f7f\u7528\u4ec5\u9650HTTP\u7684Cookie\u6765\u51cf\u8f7b\u5728\u4e4b\u524d\u7684\u6b65\u9aa4\u4e2d\u53d1\u73b0\u548c\u5229\u7528\u7684XSS\u6f0f\u6d1e\u3002<\/p>\n<p>HTTP cookies\u662f\u5b58\u50a8\u5728\u6d4f\u89c8\u5668\u4e2d\u7684\u952e\u503c\u5bf9\u5f62\u5f0f\u7684\u4fe1\u606f\u7247\u6bb5\u3002\u5b83\u4eec\u7ecf\u5e38\u7528\u4e8e\u8ddf\u8e2a\u3001\u4e2a\u6027\u5316\u6216\u4f1a\u8bdd\u7ba1\u7406\u3002<\/p>\n<p>JavaScript\u65e0\u6cd5\u901a\u8fc7Document.cookie\u5c5e\u6027\u8bbf\u95eeHTTP-only Cookie\u3002 \u8fd9\u6837\u53ef\u4ee5\u9632\u6b62\u901a\u8fc7\u6076\u610f\u4ee3\u7801\u6ce8\u5165\u8fdb\u884c\u7684XSS\u653b\u51fb\uff0c\u4ee5\u7a83\u53d6\u7528\u6237\u4fe1\u606f\u3002 \u60a8\u53ef\u4ee5\u4f7f\u7528Set-Cookie\u5934\u5728\u670d\u52a1\u5668\u7aef\u4e3a\u7ecf\u8fc7\u8eab\u4efd\u9a8c\u8bc1\u7684\u5ba2\u6237\u7aef\u8bbe\u7f6eCookie\uff0c\u5728\u5ba2\u6237\u7aef\u5bf9\u670d\u52a1\u5668\u7684\u6bcf\u4e2a\u8bf7\u6c42\u4e2d\u90fd\u53ef\u7528\uff0c\u7136\u540e\u670d\u52a1\u5668\u53ef\u4ee5\u4f7f\u7528\u5b83\u6765\u68c0\u67e5\u7528\u6237\u7684\u8eab\u4efd\u9a8c\u8bc1\u72b6\u6001\u3002 \u60a8\u5c06\u4f7f\u7528Express\u4e2d\u7684cookie-parser\u4e2d\u95f4\u4ef6\u6765\u5904\u7406\u6b64\u64cd\u4f5c\uff0c\u800c\u4e0d\u662f\u8bbe\u7f6e\u5934\u6587\u4ef6\u3002<\/p>\n<p>\u4e3a\u4e86\u5b9e\u73b0\u57fa\u4e8e\u5b89\u5168\u7684HTTP-only cookie\u7684\u4ee4\u724c\u5b58\u50a8\uff0c\u60a8\u9700\u8981\u66f4\u65b0\u4ee5\u4e0b\u6587\u4ef6\uff1a<\/p>\n<ul class=\"post-ul\">\n<li>The back-end index.js file will be modified to implement the login route so that it sets a cookie upon successful authentication. The back-end will also need two new routes: one for checking the authentication status of a user and one for logging out a user.<\/li>\n<li>The front-end Login.js and App.js files will be modified to use the new routes from the back-end.<\/li>\n<\/ul>\n<p>\u8fd9\u4e9b\u4fee\u6539\u5c06\u5728\u4f60\u7684\u5ba2\u6237\u7aef\u548c\u670d\u52a1\u5668\u4ee3\u7801\u4e2d\u5b9e\u73b0\u767b\u5f55\u3001\u6ce8\u9500\u548c\u8eab\u4efd\u9a8c\u8bc1\u72b6\u6001\u529f\u80fd\u3002<\/p>\n<p>\u79fb\u52a8\u5230\u540e\u7aef\u76ee\u5f55\u5e76\u5b89\u88c5cookie-parser\u8f6f\u4ef6\u5305\uff0c\u8be5\u8f6f\u4ef6\u5305\u5141\u8bb8\u60a8\u5728Express\u5e94\u7528\u7a0b\u5e8f\u4e2d\u8bbe\u7f6e\u548c\u8bfb\u53d6cookie\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token builtin class-name\">cd<\/span> \/app\/jwt-storage-tutorial\/back-end\r\n<\/li><li data-prefix=\"$\"><span class=\"token function\">npm<\/span> <span class=\"token function\">install<\/span> cookie-parser\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u60a8\u5c06\u770b\u5230\u4ee5\u4e0b\u8f93\u51fa\u7684\u4e00\u79cd\u53d8\u4f53\uff1a<\/p>\n<pre class=\"post-pre\"><code><div class=\"secondary-code-label\" title=\"Output\">Output<\/div>...\r\nadded 2 packages, and audited 62 packages in 1s\r\n\r\n7 packages are looking for funding\r\n  run `npm fund` for details\r\n\r\nfound 0 vulnerabilities...\r\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\uff0c\u5728\u4f60\u7684\u540e\u7aef\u5e94\u7528\u7a0b\u5e8f\u4e2d\u6253\u5f00index.js\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> \/app\/jwt-storage-tutorial\/back-end\/index.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u5c06\u4ee5\u4e0b\u7a81\u51fa\u663e\u793a\u7684\u4ee3\u7801\u6dfb\u52a0\u5230app\u4e2d\uff0c\u4f7f\u7528require\u65b9\u6cd5\u5bfc\u5165\u65b0\u5b89\u88c5\u7684cookie-parser\u5305\uff0c\u5e76\u5c06\u5176\u4f5c\u4e3a\u4e2d\u95f4\u4ef6\u4f7f\u7528\uff1a<\/p>\n<div>\u540e\u7aef\/index.js<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">const<\/span> express <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'express'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">const<\/span> cors <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cors'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<mark><span class=\"token keyword\">const<\/span> cookieParser <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cookie-parser'<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n\r\n<span class=\"token keyword\">const<\/span> app <span class=\"token operator\">=<\/span> <span class=\"token function\">express<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cors<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<mark>app<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cookieParser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">post<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'\/login'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n    res<span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">token<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"This is a secret token\"<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">listen<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">8080<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'API active on http:\/\/localhost:8080'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u4f60\u8fd8\u9700\u8981\u914d\u7f6eCORS\u4e2d\u95f4\u4ef6\u4ee5\u7ed5\u8fc7\u5f00\u53d1\u76ee\u7684\u7684CORS\u9650\u5236\u3002\u5728\u540c\u4e00\u4e2a\u6587\u4ef6\u4e2d\uff0c\u6dfb\u52a0\u5982\u4e0b\u6807\u660e\u7684\u4ee3\u7801\u884c\uff1a<\/p>\n<div>\u540e\u7aef\/index.js<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">const<\/span> express <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'express'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">const<\/span> cors <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cors'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">const<\/span> cookieParser <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cookie-parser'<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\n<span class=\"token keyword\">const<\/span> app <span class=\"token operator\">=<\/span> <span class=\"token function\">express<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<mark><span class=\"token keyword\">let<\/span> corsOptions <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n  <mark><span class=\"token literal-property property\">origin<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'http:\/\/localhost:3000'<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n  <mark><span class=\"token literal-property property\">credentials<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n<mark><span class=\"token punctuation\">}<\/span><\/mark>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cors<\/span><span class=\"token punctuation\">(<\/span><mark>corsOptions<\/mark><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cookieParser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">post<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'\/login'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n    res<span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">token<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"This is a secret token\"<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">listen<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">8080<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'API active on http:\/\/localhost:8080'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u4f60\u53ef\u4ee5\u5728corsOptions\u5bf9\u8c61\u7684origin\u9009\u9879\u4e0b\u8bbe\u7f6eAccess-Control-Allow-Origin CORS\u5934\u90e8\u3002\u8fd9\u4e2aorigin\u9009\u9879\u5e94\u8be5\u8bbe\u7f6e\u4e3a\u4f60\u7684\u524d\u7aef\u53d1\u9001API\u8bf7\u6c42\u7684\u57df\u540d\u3002\u4f60\u8fd8\u9700\u8981\u5c06credentials\u53c2\u6570\u8bbe\u7f6e\u4e3atrue\uff0c\u544a\u8bc9\u524d\u7aef\u5728\u6bcf\u4e2aAPI\u8bf7\u6c42\u4e2d\u53d1\u9001\u6388\u6743\u4ee4\u724c\u7684cookie\u3002origin\u9009\u9879\u7684\u503c\u6307\u5b9a\u4e86\u63a5\u53d7\u6765\u81ea\u54ea\u4e9b\u57df\u7684\u8bbf\u95ee\u63a7\u5236\u6570\u636e\uff0c\u6bd4\u5982cookie\uff0c\u7528\u4e8e\u540e\u7aef\u5904\u7406\u3002<\/p>\n<p>\u6700\u540e\uff0c\u5c06corsOptions\u7684\u914d\u7f6e\u5bf9\u8c61\u4f20\u9012\u7ed9cors\u4e2d\u95f4\u4ef6\u5bf9\u8c61\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u60a8\u5c06\u4f7f\u7528cookie-parser\u4e2d\u95f4\u4ef6\u5728\u8def\u7531\u5904\u7406\u7a0b\u5e8f\u7684\u54cd\u5e94\u5bf9\u8c61\u4e0a\u63d0\u4f9b\u7684cookie()\u65b9\u6cd5\u8bbe\u7f6e\u7528\u6237\u7684cookie\u4ee4\u724c\u3002\u5c06app.use(&#8216;\/login&#8217;, (req, res)\u90e8\u5206\u4e2d\u7684\u884c\u66ff\u6362\u4e3a\u7a81\u51fa\u663e\u793a\u7684\u884c\uff1a<\/p>\n<div>\u540e\u7aef\/index.js<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">const<\/span> express <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'express'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">const<\/span> cors <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cors'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">const<\/span> cookieParser <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cookie-parser'<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\n<span class=\"token keyword\">const<\/span> app <span class=\"token operator\">=<\/span> <span class=\"token function\">express<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">let<\/span> corsOptions <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token literal-property property\">origin<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'http:\/\/localhost:3000'<\/span><span class=\"token punctuation\">,<\/span>\r\n  <span class=\"token literal-property property\">credentials<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cors<\/span><span class=\"token punctuation\">(<\/span>corsOptions<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cookieParser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'\/login'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <mark>res<span class=\"token punctuation\">.<\/span><span class=\"token function\">cookie<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">\"token\"<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">\"this is a secret token\"<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">httpOnly<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">maxAge<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">1000<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">60<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">60<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">24<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">14<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token comment\">\/\/ 14 Day Age,<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">domain<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"localhost\"<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">sameSite<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'Lax'<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n    <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">authenticated<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">message<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"Authentication Successful.\"<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">listen<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">8080<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'API active on http:\/\/localhost:8080'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u5728\u4e0a\u9762\u7684\u4ee3\u7801\u5757\u4e2d\uff0c\u60a8\u4f7f\u7528\u952e\u4e3atoken\uff0c\u503c\u4e3athis is a secret token\u6765\u8bbe\u7f6e\u4e86\u4e00\u4e2acookie\u3002httpOnly\u914d\u7f6e\u9009\u9879\u8bbe\u7f6e\u4e86httpOnly\u5c5e\u6027\uff0c\u4ee5\u4fbf\u8be5cookie\u5bf9\u6587\u6863\u4e0a\u8fd0\u884c\u7684JavaScript\u4e0d\u53ef\u8bbf\u95ee\u3002<\/p>\n<p>\u60a8\u8bbe\u7f6e\u4e86maxAge\u5c5e\u6027\uff0c\u4f7f\u5f97cookie\u572814\u5929\u540e\u8fc7\u671f\u300214\u5929\u540e\uff0ccookie\u5c06\u4f1a\u8fc7\u671f\uff0c\u6d4f\u89c8\u5668\u5c06\u9700\u8981\u4e00\u4e2a\u65b0\u7684\u8eab\u4efd\u9a8c\u8bc1cookie\u3002\u56e0\u6b64\uff0c\u7528\u6237\u9700\u8981\u4f7f\u7528\u4ed6\u4eec\u7684\u7528\u6237\u540d\u548c\u5bc6\u7801\u518d\u6b21\u767b\u5f55\u3002<\/p>\n<p>\u4e3a\u4e86\u786e\u4fdd\u5ba2\u6237\u7aef\u6d4f\u89c8\u5668\u4e0d\u56e0\u8de8\u57df\u8d44\u6e90\u5171\u4eab\uff08CORS\uff09\u6216\u5176\u4ed6\u5b89\u5168\u534f\u8bae\u95ee\u9898\u800c\u62d2\u7edd\u63a5\u53d7\u60a8\u7684Cookie\uff0c\u9700\u8981\u8bbe\u7f6esameSite\u548cdomain\u5c5e\u6027\u3002<\/p>\n<p>\u65e2\u7136\u4f60\u5df2\u7ecf\u6709\u4e86\u767b\u5f55\u7684\u8def\u5f84\uff0c\u4f60\u73b0\u5728\u9700\u8981\u4e00\u4e2a\u9000\u51fa\u7684\u8def\u5f84\u3002\u8bf7\u6dfb\u52a0\u4ee5\u4e0b\u7a81\u51fa\u663e\u793a\u7684\u4ee3\u7801\u6765\u8bbe\u7f6e\u9000\u51fa\u7684\u65b9\u6cd5\uff1a<\/p>\n<div>\u540e\u7aef\/\u7d22\u5f15.js (H\u00f2udu\u0101n\/su\u01d2y\u01d0n.js)<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">const<\/span> express <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'express'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">const<\/span> cors <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cors'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">const<\/span> cookieParser <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cookie-parser'<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\n<span class=\"token keyword\">const<\/span> app <span class=\"token operator\">=<\/span> <span class=\"token function\">express<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">let<\/span> corsOptions <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token literal-property property\">origin<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'http:\/\/localhost:3000'<\/span><span class=\"token punctuation\">,<\/span>\r\n  <span class=\"token literal-property property\">credentials<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cors<\/span><span class=\"token punctuation\">(<\/span>corsOptions<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cookieParser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'\/login'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n    res<span class=\"token punctuation\">.<\/span><span class=\"token function\">cookie<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">\"token\"<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">\"this is a secret token\"<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">httpOnly<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">maxAge<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">1000<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">60<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">60<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">24<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">14<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token comment\">\/\/ 14 Day Age,<\/span>\r\n      <span class=\"token literal-property property\">domain<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"localhost\"<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">sameSite<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'Lax'<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">authenticated<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">message<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"Authentication Successful.\"<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<mark>app<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'\/logout'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n  <mark>res<span class=\"token punctuation\">.<\/span><span class=\"token function\">cookie<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">\"token\"<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark><span class=\"token literal-property property\">httpOnly<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n    <mark><span class=\"token literal-property property\">maxAge<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">1000<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">60<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">60<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">24<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">14<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token comment\">\/\/ 14 Day Age,<\/span><\/mark>\r\n    <mark><span class=\"token literal-property property\">domain<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"localhost\"<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n    <mark><span class=\"token literal-property property\">sameSite<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'Lax'<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark><span class=\"token literal-property property\">authenticated<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n    <mark><span class=\"token literal-property property\">message<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"Logout Successful.\"<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n<mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">listen<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">8080<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'API active on http:\/\/localhost:8080'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u9000\u51fa\u65b9\u6cd5\u7c7b\u4f3c\u4e8e\u767b\u5f55\u8def\u7531\u3002\u9000\u51fa\u65b9\u6cd5\u5c06\u901a\u8fc7\u5c06\u4ee4\u724c cookie \u8bbe\u7f6e\u4e3a null \u6765\u5220\u9664\u7528\u6237\u5b58\u50a8\u7684\u4ee4\u724c\u3002\u7136\u540e\uff0c\u5b83\u4f1a\u901a\u77e5\u7528\u6237\u5df2\u6210\u529f\u9000\u51fa\u767b\u5f55\u3002<\/p>\n<p>\u6700\u540e\uff0c\u6dfb\u52a0\u4e0a\u9762\u6807\u51fa\u7684\u4ee3\u7801\u884c\uff0c\u5b9e\u73b0\u4e00\u4e2a\u8ba4\u8bc1\u72b6\u6001\u8def\u7531\uff0c\u8ba9\u7528\u6237\u5ba2\u6237\u7aef\u53ef\u4ee5\u68c0\u67e5\u7528\u6237\u662f\u5426\u5df2\u767b\u5f55\u5e76\u5141\u8bb8\u8bbf\u95ee\u79c1\u6709\u8d44\u6e90\u3002<\/p>\n<div>\u540e\u7aef\/\u7d22\u5f15.js<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">const<\/span> express <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'express'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">const<\/span> cors <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cors'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">const<\/span> cookieParser <span class=\"token operator\">=<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'cookie-parser'<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\n<span class=\"token keyword\">const<\/span> app <span class=\"token operator\">=<\/span> <span class=\"token function\">express<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">let<\/span> corsOptions <span class=\"token operator\">=<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token literal-property property\">origin<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'http:\/\/localhost:3000'<\/span><span class=\"token punctuation\">,<\/span>\r\n  <span class=\"token literal-property property\">credentials<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cors<\/span><span class=\"token punctuation\">(<\/span>corsOptions<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token function\">cookieParser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'\/login'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n    res<span class=\"token punctuation\">.<\/span><span class=\"token function\">cookie<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">\"token\"<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">\"this is a secret token\"<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">httpOnly<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">maxAge<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">1000<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">60<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">60<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">24<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">14<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token comment\">\/\/ 14 Day Age,<\/span>\r\n      <span class=\"token literal-property property\">domain<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"localhost\"<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">sameSite<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'Lax'<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">authenticated<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">message<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"Authentication Successful.\"<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'\/logout'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n  res<span class=\"token punctuation\">.<\/span><span class=\"token function\">cookie<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">\"token\"<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">null<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token literal-property property\">httpOnly<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token literal-property property\">maxAge<\/span><span class=\"token operator\">:<\/span> <span class=\"token number\">1000<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">60<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">60<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">24<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">14<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token comment\">\/\/ 14 Day Age,<\/span>\r\n    <span class=\"token literal-property property\">domain<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"localhost\"<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token literal-property property\">sameSite<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'Lax'<\/span><span class=\"token punctuation\">,<\/span>\r\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token literal-property property\">authenticated<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token literal-property property\">message<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">\"Logout Successful.\"<\/span>\r\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<mark>app<span class=\"token punctuation\">.<\/span><span class=\"token function\">use<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'\/auth-status'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n  <mark>console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span>req<span class=\"token punctuation\">.<\/span>cookies<span class=\"token punctuation\">)<\/span><\/mark>\r\n\r\n  <mark><span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>req<span class=\"token punctuation\">.<\/span>cookies<span class=\"token operator\">?.<\/span>token <span class=\"token operator\">===<\/span> <span class=\"token string\">\"this is a secret token\"<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark>res<span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token literal-property property\">isAuthenticated<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark>res<span class=\"token punctuation\">.<\/span><span class=\"token function\">send<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><span class=\"token literal-property property\">isAuthenticated<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span><\/mark>\r\n<mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n\r\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">listen<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">8080<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'API active on http:\/\/localhost:8080'<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u60a8\u7684 auth-status \u8def\u7531\u4f1a\u68c0\u67e5\u662f\u5426\u5b58\u5728\u4e0e\u7528\u6237\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u7684\u9884\u671f\u503c\u5339\u914d\u7684\u4ee4\u724c cookie\u3002\u7136\u540e\uff0c\u5b83\u4f1a\u56de\u5e94\u4e00\u4e2a\u5e03\u5c14\u503c\u6765\u6307\u793a\u7528\u6237\u662f\u5426\u5df2\u7ecf\u901a\u8fc7\u8eab\u4efd\u9a8c\u8bc1\u3002<\/p>\n<p>\u5f53\u5b8c\u6210\u65f6\uff0c\u8bf7\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002\u60a8\u5df2\u5728\u540e\u7aef\u8fdb\u884c\u4e86\u5fc5\u8981\u7684\u66f4\u6539\uff0c\u4ee5\u4f7f\u60a8\u7684\u524d\u7aef\u80fd\u591f\u901a\u8fc7\u540e\u7aefAPI\u8ddf\u8e2a\u7528\u6237\u7684\u8ba4\u8bc1\u72b6\u6001\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u60a8\u5c06\u8fdb\u884c\u5fc5\u8981\u7684\u524d\u7aef\u66f4\u6539\uff0c\u4ee5\u5b9e\u73b0\u57fa\u4e8eHTTP\u7684\u4ec5Cookie\u5b58\u50a8\u7684\u4ee4\u724c\u529f\u80fd\u3002<\/p>\n<p>\u524d\u5f80\u524d\u7aef\u76ee\u5f55\u5e76\u6253\u5f00Login.js\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token builtin class-name\">cd<\/span> <span class=\"token punctuation\">..<\/span>\r\n<\/li><li data-prefix=\"$\"><span class=\"token builtin class-name\">cd<\/span> front-end\/src\/components\/\r\n<\/li><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> Login.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u8bf7\u5c06\u9ad8\u4eae\u7684\u884c\u6dfb\u52a0\u5230\u60a8\u7684\u767b\u5f55\u7ec4\u4ef6\u4e2d\u7684loginUser\u51fd\u6570\u4e2d\u8fdb\u884c\u4fee\u6539\uff1a<\/p>\n<div>jwt-storage-tutorial\/front-end\/src\/components\/Login.js \u7684\u4e2d\u6587\u540c\u4e49\u8868\u8ff0\u5982\u4e0b\uff1a\u767b\u5f55\u7ec4\u4ef6\u3002<\/div>\n<pre class=\"post-pre\"><code><span class=\"token operator\">...<\/span>\r\n\r\n<span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">loginUser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">credentials<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">return<\/span> <span class=\"token function\">fetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'http:\/\/localhost:8080\/login'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token literal-property property\">method<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'POST'<\/span><span class=\"token punctuation\">,<\/span>\r\n    <mark><span class=\"token literal-property property\">credentials<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'include'<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n    <span class=\"token literal-property property\">headers<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token string-property property\">'Content-Type'<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'application\/json'<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token literal-property property\">body<\/span><span class=\"token operator\">:<\/span> <span class=\"token constant\">JSON<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">stringify<\/span><span class=\"token punctuation\">(<\/span>credentials<span class=\"token punctuation\">)<\/span>\r\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">data<\/span> <span class=\"token operator\">=&gt;<\/span> data<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token operator\">...<\/span>            \r\n<\/code><\/pre>\n<p>\u4f60\u53ef\u4ee5\u5c06\u4f60\u7684fetch\u8bf7\u6c42\u7684credentials header\u8bbe\u7f6e\u4e3a\u201cinclude\u201d\uff0c\u8fd9\u6837\u5c31\u4f1a\u544a\u8bc9loginUser\u51fd\u6570\u5728\u53d1\u9001\u5230\u5df2\u5728\u540e\u7aef\u4fee\u6539\u8fc7\u7684\u767b\u5f55\u8def\u5f84\u7684API\u8c03\u7528\u65f6\uff0c\u53d1\u9001\u4efb\u4f55\u53ef\u80fd\u8bbe\u7f6e\u4e3acookie\u7684\u51ed\u636e\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u60a8\u5c06\u4ece\u767b\u5f55\u7ec4\u4ef6\u4e2d\u79fb\u9664setToken\u8f93\u5165\u5c5e\u6027\u4ee5\u53ca\u5c06\u5176\u5728handleSubmit\u56de\u8c03\u672b\u5c3e\u7684\u4f7f\u7528\uff0c\u56e0\u4e3a\u60a8\u4e0d\u518d\u5c06\u4ee4\u724c\u4fdd\u7559\u5728\u5185\u5b58\u4e2d\u3002<\/p>\n<p>\u5728handlesubmit\u51fd\u6570\u7ed3\u675f\u65f6\uff0c\u60a8\u8fd8\u9700\u8981\u89e6\u53d1\u4e00\u6b21\u5237\u65b0\uff0c\u4ee5\u4fbf\u5728\u5355\u51fb\u767b\u5f55\u6309\u94ae\u540e\u5237\u65b0\u5e94\u7528\u7a0b\u5e8f\uff0c\u5e76\u901a\u8fc7\u5ba2\u6237\u7aef\u5e94\u7528\u7a0b\u5e8f\u8bc6\u522b\u65b0\u8bbe\u7f6e\u7684\u4ee4\u724ccookie\u3002\u6dfb\u52a0\u4ee5\u4e0b\u7a81\u51fa\u663e\u793a\u7684\u884c\uff1a<\/p>\n<div>\u6559\u7a0b\u5e94\u5b58\u50a8\u5728JWT-STORAGE\u524d\u7aef\u7ec4\u4ef6\u7684Login.js\u6587\u4ef6\u4e2d\u3002<\/div>\n<pre class=\"post-pre\"><code><span class=\"token operator\">...<\/span>\r\n  <span class=\"token keyword\">const<\/span> <span class=\"token function-variable function\">handleSubmit<\/span> <span class=\"token operator\">=<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">e<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n    e<span class=\"token punctuation\">.<\/span><span class=\"token function\">preventDefault<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n    <span class=\"token keyword\">const<\/span> token <span class=\"token operator\">=<\/span> <span class=\"token keyword\">await<\/span> <span class=\"token function\">loginUser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span>\r\n        <span class=\"token literal-property property\">username<\/span><span class=\"token operator\">:<\/span> emailRef<span class=\"token punctuation\">.<\/span>current<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token literal-property property\">password<\/span><span class=\"token operator\">:<\/span> passwordRef<span class=\"token punctuation\">.<\/span>current<span class=\"token punctuation\">.<\/span>value\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span>\r\n    <mark>window<span class=\"token punctuation\">.<\/span>location<span class=\"token punctuation\">.<\/span><span class=\"token function\">reload<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n  <span class=\"token punctuation\">}<\/span>\r\n<span class=\"token operator\">...<\/span>\r\n<\/code><\/pre>\n<p>\u4f60\u7684Login.js\u6587\u4ef6\u73b0\u5728\u5e94\u8be5\u770b\u8d77\u6765\u50cf\u8fd9\u6837\uff1a<\/p>\n<div>\u8bf7\u7528\u4e2d\u6587\u5c06\u4ee5\u4e0b\u5185\u5bb9\u8fdb\u884c\u91cd\u65b0\u8868\u8fbe\uff0c\u53ea\u9700\u8981\u4e00\u4e2a\u9009\u9879\uff1a<br \/>\njwt-storage-tutorial\/front-end\/src\/components\/Login.js<\/p>\n<p>JWT\u5b58\u50a8\u6559\u7a0b\/\u524d\u7aef\/\u6e90\u4ee3\u7801\/\u7ec4\u4ef6\/Login.js<\/p><\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> React<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> useRef <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">loginUser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">credentials<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">return<\/span> <span class=\"token function\">fetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'http:\/\/localhost:8080\/login'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token literal-property property\">method<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'POST'<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token literal-property property\">credentials<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'include'<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token literal-property property\">headers<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token string-property property\">'Content-Type'<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'application\/json'<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token literal-property property\">body<\/span><span class=\"token operator\">:<\/span> <span class=\"token constant\">JSON<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">stringify<\/span><span class=\"token punctuation\">(<\/span>credentials<span class=\"token punctuation\">)<\/span>\r\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">data<\/span> <span class=\"token operator\">=&gt;<\/span> data<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">const<\/span> emailRef <span class=\"token operator\">=<\/span> <span class=\"token function\">useRef<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token keyword\">const<\/span> passwordRef <span class=\"token operator\">=<\/span> <span class=\"token function\">useRef<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n  <span class=\"token keyword\">const<\/span> <span class=\"token function-variable function\">handleSubmit<\/span> <span class=\"token operator\">=<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">e<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n    e<span class=\"token punctuation\">.<\/span><span class=\"token function\">preventDefault<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n    <span class=\"token keyword\">const<\/span> token <span class=\"token operator\">=<\/span> <span class=\"token keyword\">await<\/span> <span class=\"token function\">loginUser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span>\r\n        <span class=\"token literal-property property\">username<\/span><span class=\"token operator\">:<\/span> emailRef<span class=\"token punctuation\">.<\/span>current<span class=\"token punctuation\">.<\/span>value<span class=\"token punctuation\">,<\/span>\r\n        <span class=\"token literal-property property\">password<\/span><span class=\"token operator\">:<\/span> passwordRef<span class=\"token punctuation\">.<\/span>current<span class=\"token punctuation\">.<\/span>value\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span>\r\n    window<span class=\"token punctuation\">.<\/span>location<span class=\"token punctuation\">.<\/span><span class=\"token function\">reload<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token punctuation\">}<\/span>\r\n\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">'login-wrapper'<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>h1<span class=\"token operator\">&gt;<\/span>Login<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>form onSubmit<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>handleSubmit<span class=\"token punctuation\">}<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>Username<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>input type<span class=\"token operator\">=<\/span><span class=\"token string\">\"text\"<\/span> ref<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>emailRef<span class=\"token punctuation\">}<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>p<span class=\"token operator\">&gt;<\/span>Password<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>p<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>input type<span class=\"token operator\">=<\/span><span class=\"token string\">\"password\"<\/span> ref<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>passwordRef<span class=\"token punctuation\">}<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>label<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>button type<span class=\"token operator\">=<\/span><span class=\"token string\">\"submit\"<\/span><span class=\"token operator\">&gt;<\/span>Submit<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>button<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>form<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n<\/code><\/pre>\n<p>\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u7531\u4e8e\u60a8\u4e0d\u518d\u5c06\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u4fdd\u5b58\u5728\u5185\u5b58\u4e2d\uff0c\u56e0\u6b64\u5f53\u60a8\u9700\u8981\u786e\u5b9a\u7528\u6237\u662f\u5426\u5e94\u8be5\u767b\u5f55\u6216\u8bbf\u95ee\u79c1\u6709\u8d44\u4ea7\u65f6\uff0c\u65e0\u6cd5\u68c0\u67e5\u662f\u5426\u5b58\u5728\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u3002<\/p>\n<p>\u4e3a\u4e86\u8fdb\u884c\u8fd9\u4e9b\u66f4\u6539\uff0c\u8bf7\u6253\u5f00\u4f60\u7684\u524d\u7aefApp.js\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><ol><li data-prefix=\"$\"><span class=\"token builtin class-name\">cd<\/span> <span class=\"token punctuation\">..<\/span>\r\n<\/li><li data-prefix=\"$\"><span class=\"token function\">nano<\/span> App.js\r\n<\/li><\/ol>\r\n<\/code><\/pre>\n<p>\u4eceReact\u5305\u4e2d\u5bfc\u5165useState hook\uff0c\u5e76\u521d\u59cb\u5316\u4e00\u4e2a\u65b0\u7684\u7ecf\u8fc7\u8eab\u4efd\u9a8c\u8bc1\u7684\u72b6\u6001\u53d8\u91cf\uff0c\u4ee5\u53ca\u7528\u4e8e\u53cd\u6620\u7528\u6237\u8ba4\u8bc1\u72b6\u6001\u7684setter\uff1a<\/p>\n<div>jwt-storage-tutorial\/front-end\/src\/App.js \u7684\u4e2d\u6587\u672c\u571f\u5316\u7248\u672c\u3002<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useState <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span>\r\n\r\n<span class=\"token operator\">...<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <mark><span class=\"token keyword\">let<\/span> <span class=\"token punctuation\">[<\/span>authenticated<span class=\"token punctuation\">,<\/span> setAuthenticated<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">useState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n\r\n  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>token<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token keyword\">return<\/span> <span class=\"token operator\">&lt;<\/span>Login setToken<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>setToken<span class=\"token punctuation\">}<\/span> <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">}<\/span>\r\n\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App wrapper\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>h1 className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token constant\">JWT<\/span><span class=\"token operator\">-<\/span>Storage<span class=\"token operator\">-<\/span>Tutorial Application\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/subscriber-feed\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n            <span class=\"token operator\">&lt;<\/span>SubscriberFeed <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>useState\u94a9\u5b50\u5c06\u901a\u8fc7\u5411\u540e\u7aefAPI\u53d1\u9001\u8bf7\u6c42\u6765\u68c0\u67e5\u7528\u6237\u7684\u8eab\u4efd\u9a8c\u8bc1\u72b6\u6001\uff0c\u8be5API\u80fd\u591f\u5224\u65ad\u524d\u7aef\u5ba2\u6237\u7aef\u662f\u5426\u6301\u6709\u6709\u6548\u7684\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u4f5c\u4e3acookie\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u5220\u9664setToken\u548cgetToken\u51fd\u6570\uff0ctoken\u53d8\u91cf\u4ee5\u53ca\u767b\u5f55\u7ec4\u4ef6\u7684\u6761\u4ef6\u6e32\u67d3\u90e8\u5206\u3002\u7136\u540e\uff0c\u4f7f\u7528\u4e0b\u9762\u7684\u7a81\u51fa\u663e\u793a\u7684\u4ee3\u7801\u884c\u521b\u5efa\u4e24\u4e2a\u65b0\u51fd\u6570\uff0c\u5206\u522b\u547d\u540d\u4e3agetAuthStatus\u548cisAuthenticated\u3002<\/p>\n<div>\u8bf7\u628a\u4ee5\u4e0b\u5185\u5bb9\u7528\u4e2d\u6587\u8868\u8fbe\uff0c\u53ea\u63d0\u4f9b\u4e00\u79cd\u9009\u9879\uff1a<br \/>\njwt-storage-tutorial\/front-end\/src\/App.js<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useState <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> BrowserRouter<span class=\"token punctuation\">,<\/span> Route<span class=\"token punctuation\">,<\/span> Switch <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> SubscriberFeed <span class=\"token keyword\">from<\/span> <span class=\"token string\">\".\/components\/SubscriberFeed\"<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> Login <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/components\/Login'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">let<\/span> <span class=\"token punctuation\">[<\/span>authenticated<span class=\"token punctuation\">,<\/span> setAuthenticated<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">useState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n  <mark><span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">getAuthStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark><span class=\"token keyword\">return<\/span> <span class=\"token function\">fetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'http:\/\/localhost:8080\/auth-status'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">method<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'GET'<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">credentials<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'include'<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">headers<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n        <mark><span class=\"token string-property property\">'Content-Type'<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'application\/json'<\/span><\/mark>\r\n      <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n    <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">data<\/span> <span class=\"token operator\">=&gt;<\/span> data<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span><\/mark>\r\n\r\n  <mark><span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">isAuthenticated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark><span class=\"token keyword\">const<\/span> authStatus <span class=\"token operator\">=<\/span> <span class=\"token keyword\">await<\/span> <span class=\"token function\">getAuthStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n    <mark><span class=\"token function\">setAuthenticated<\/span><span class=\"token punctuation\">(<\/span>authStatus<span class=\"token punctuation\">.<\/span>isAuthenticated<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span><\/mark>\r\n\r\n  <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App wrapper\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>h1 className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token constant\">JWT<\/span><span class=\"token operator\">-<\/span>Storage<span class=\"token operator\">-<\/span>Tutorial Application\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/subscriber-feed\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n            <span class=\"token operator\">&lt;<\/span>SubscriberFeed <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>    \r\n<\/code><\/pre>\n<p>getAuthStatus\u51fd\u6570\u5c06\u5411\u540e\u7aef\u5e94\u7528\u7a0b\u5e8f\u7684auth-status\u8def\u7531\u53d1\u51faGET\u8bf7\u6c42\uff0c\u4ee5\u83b7\u53d6\u7528\u6237\u7684\u8eab\u4efd\u9a8c\u8bc1\u72b6\u6001\uff0c\u5177\u4f53\u53d6\u51b3\u4e8e\u7528\u6237\u662f\u5426\u4f7f\u7528\u6709\u6548\u7684\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724ccookie\u53d1\u9001\u8bf7\u6c42\u3002<\/p>\n<p>\u901a\u8fc7\u5c06\u51ed\u636e\u9009\u9879\u7684\u503c\u8bbe\u7f6e\u4e3a\u5305\u62ec\uff0cfetch\u51fd\u6570\u5c06\u53d1\u9001\u6d4f\u89c8\u5668\u4e3a\u7528\u6237\u5ba2\u6237\u7aef\u53ef\u80fd\u5b58\u50a8\u7684\u4efb\u4f55\u51ed\u636e\uff0c\u5982cookies\u3002isAuthenticated\u51fd\u6570\u5c06\u8c03\u7528getAuthStatus\u51fd\u6570\uff0c\u5e76\u5c06\u60a8\u7684\u5e94\u7528\u7a0b\u5e8f\u7684\u8ba4\u8bc1\u72b6\u6001\u8bbe\u7f6e\u4e3a\u53cd\u6620\u7528\u6237\u8ba4\u8bc1\u72b6\u6001\u7684\u5e03\u5c14\u503c\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u60a8\u5c06\u4f7f\u7528\u4e0b\u9762\u6807\u8bb0\u7684\u884c\u5bfc\u5165useEffect\u94a9\u5b50\u3002<\/p>\n<div>jwt-storage-tutorial\/front-end\/src\/App.js\u7684\u4e2d\u6587\u91ca\u4e49\u5982\u4e0b:<\/p>\n<p>\u5728jwt-storage-tutorial\/front-end\/src\/App.js\u4e2d\u7684\u89e3\u91ca\u5982\u4e0b:<\/p><\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useState<mark><span class=\"token punctuation\">,<\/span> useEffect<\/mark> <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> BrowserRouter<span class=\"token punctuation\">,<\/span> Route<span class=\"token punctuation\">,<\/span> Switch <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> SubscriberFeed <span class=\"token keyword\">from<\/span> <span class=\"token string\">\".\/components\/SubscriberFeed\"<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> Login <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/components\/Login'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">let<\/span> <span class=\"token punctuation\">[<\/span>authenticated<span class=\"token punctuation\">,<\/span> setAuthenticated<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">useState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n  <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">getAuthStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token keyword\">return<\/span> <span class=\"token function\">fetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'http:\/\/localhost:8080\/auth-status'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">method<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'GET'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">credentials<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'include'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">headers<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span>\r\n        <span class=\"token string-property property\">'Content-Type'<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'application\/json'<\/span>\r\n      <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">data<\/span> <span class=\"token operator\">=&gt;<\/span> data<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>\r\n  <span class=\"token punctuation\">}<\/span>\r\n\r\n  <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">isAuthenticated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token keyword\">const<\/span> authStatus <span class=\"token operator\">=<\/span> <span class=\"token keyword\">await<\/span> <span class=\"token function\">getAuthStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n    <span class=\"token function\">setAuthenticated<\/span><span class=\"token punctuation\">(<\/span>authStatus<span class=\"token punctuation\">.<\/span>isAuthenticated<span class=\"token punctuation\">)<\/span>\r\n  <span class=\"token punctuation\">}<\/span>\r\n\r\n  <mark><span class=\"token function\">useEffect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark><span class=\"token function\">isAuthenticated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n\r\n<span class=\"token operator\">...<\/span>\r\n<\/code><\/pre>\n<p>\u8fd9\u4e2a\u4fee\u6539\u5c06\u5728useEffect hook\u4e2d\u8c03\u7528\u767b\u5f55\u8def\u7531\u6765\u68c0\u67e5\u8eab\u4efd\u9a8c\u8bc1\u72b6\u6001\u3002\u5728useEffect hook\u4e2d\u5305\u542b\u4e00\u4e2a\u7a7a\u7684\u4f9d\u8d56\u6570\u7ec4\u53ef\u4ee5\u5e2e\u52a9\u907f\u514d\u5e94\u7528\u7a0b\u5e8f\u4e2d\u7684\u5185\u5b58\u6cc4\u6f0f\u3002<\/p>\n<p>\u5728\u5e94\u7528\u4e3b\u9875\u4e0a\u6709\u4e00\u4e2a\u6761\u4ef6\u6e32\u67d3\u767b\u5f55\u7ec4\u4ef6\u7684\u65b9\u5f0f\uff0c\u53ea\u9700\u8981\u6dfb\u52a0\u4e0b\u9762\u7a81\u51fa\u7684\u4ee3\u7801\u884c\uff1a<\/p>\n<div>\u5728jwt-storage-tutorial\/front-end\/src\/App.js\u6587\u4ef6\u4e2d<\/div>\n<pre class=\"post-pre\"><code><span class=\"token operator\">...<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">let<\/span> <span class=\"token punctuation\">[<\/span>authenticated<span class=\"token punctuation\">,<\/span> setAuthenticated<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">useState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n  <mark><span class=\"token keyword\">let<\/span> <span class=\"token punctuation\">[<\/span>loading<span class=\"token punctuation\">,<\/span> setLoading<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">useState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n\r\n  <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">getAuthStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <mark><span class=\"token keyword\">await<\/span> <span class=\"token function\">setLoading<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n    <span class=\"token keyword\">return<\/span> <span class=\"token function\">fetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'http:\/\/localhost:8080\/auth-status'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">method<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'GET'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">credentials<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'include'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">headers<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span>\r\n        <span class=\"token string-property property\">'Content-Type'<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'application\/json'<\/span>\r\n      <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">data<\/span> <span class=\"token operator\">=&gt;<\/span> data<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>\r\n  <span class=\"token punctuation\">}<\/span>\r\n\r\n  <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">isAuthenticated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token keyword\">const<\/span> authStatus <span class=\"token operator\">=<\/span> <span class=\"token keyword\">await<\/span> <span class=\"token function\">getAuthStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n    <mark><span class=\"token keyword\">await<\/span><\/mark> <span class=\"token function\">setAuthenticated<\/span><span class=\"token punctuation\">(<\/span>authStatus<span class=\"token punctuation\">.<\/span>isAuthenticated<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n    <mark><span class=\"token keyword\">await<\/span> <span class=\"token function\">setLoading<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n  <span class=\"token punctuation\">}<\/span>\r\n\r\n  <span class=\"token function\">useEffect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token function\">isAuthenticated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\n  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">(<\/span>\r\n    <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n      <mark><span class=\"token punctuation\">{<\/span><span class=\"token operator\">!<\/span>loading <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token punctuation\">(<\/span><\/mark>\r\n        <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n          <mark><span class=\"token punctuation\">{<\/span><span class=\"token operator\">!<\/span>authenticated <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token operator\">&lt;<\/span>Login <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">}<\/span><\/mark>\r\n\r\n          <mark><span class=\"token punctuation\">{<\/span>authenticated <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token punctuation\">(<\/span><\/mark>\r\n            <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App wrapper\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n              <span class=\"token operator\">&lt;<\/span>h1 className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n                <span class=\"token constant\">JWT<\/span><span class=\"token operator\">-<\/span>Storage<span class=\"token operator\">-<\/span>Tutorial Application\r\n              <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n              <span class=\"token operator\">&lt;<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n                <span class=\"token operator\">&lt;<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n                  <span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/subscriber-feed\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n                    <span class=\"token operator\">&lt;<\/span>SubscriberFeed <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n                  <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span>\r\n                  <span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/xss-helper\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n                    <span class=\"token operator\">&lt;<\/span>XSSHelper <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n                  <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span>\r\n                <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n              <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n            <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n          <mark><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">}<\/span><\/mark>\r\n        <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n      <mark><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">}<\/span><\/mark>\r\n    <mark><span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span><\/mark>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u5982\u679c\u8ba4\u8bc1\u7684\u53d8\u91cf\u8bbe\u7f6e\u4e3afalse\uff0c\u4f60\u7684\u5e94\u7528\u5c06\u6e32\u67d3\u767b\u5f55\u7ec4\u4ef6\u3002\u5426\u5219\uff0c\u5e94\u7528\u7684\u4e3b\u9875\u548c\u5176\u6240\u6709\u7684\u8def\u7531\uff0c\u5305\u62ec\u79c1\u6709\u9875\u9762\uff0c\u5c06\u4f1a\u6e32\u67d3\u3002<\/p>\n<p>\u4f60\u6dfb\u52a0\u4e86\u4e00\u4e2a\u65b0\u7684\u52a0\u8f7d\u72b6\u6001\u53d8\u91cf\uff0c\u4ee5\u907f\u514d\u5728\u5b8c\u6210\u5230\u4f60\u7684\u540e\u7aef\u5e94\u7528\u7a0b\u5e8f\u7684\u8ba4\u8bc1\u72b6\u6001\u8def\u7531\u7684\u8c03\u7528\u4e4b\u524d\u6e32\u67d3\u4efb\u4f55\u5185\u5bb9\u3002\u56e0\u4e3a\u8ba4\u8bc1\u72b6\u6001\u53d8\u91cf\u6700\u521d\u4e3afalse\uff0c\u5ba2\u6237\u7aef\u4f1a\u5047\u5b9a\u7528\u6237\u5c1a\u672a\u767b\u5f55\uff0c\u76f4\u5230\u8ba4\u8bc1\u72b6\u6001\u8def\u7531\u7684API\u8c03\u7528\u5b8c\u6210\u5e76\u66f4\u65b0\u8ba4\u8bc1\u72b6\u6001\u53d8\u91cf\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u4f60\u5c06\u521b\u5efa\u4e00\u4e2alogoutUser\u51fd\u6570\uff0c\u5728\u540e\u7aefAPI\u4e0a\u8c03\u7528\u4f60\u7684\u767b\u51fa\u8def\u7531\u3002\u5c06\u4ee5\u4e0b\u884c\u6dfb\u52a0\u5230\u6587\u4ef6\u4e2d\uff1a<\/p>\n<div>\u5c06\u4ee5\u4e0b\u7684\u539f\u6587\u4ee5\u4e2d\u56fd\u5927\u9646\u7684\u6bcd\u8bed\u8fdb\u884c\u91ca\u4e49\uff08\u53ea\u63d0\u4f9b\u4e00\u4e2a\u9009\u9879\uff09\uff1ajwt-storage-tutorial\/front-end\/src\/App.js<\/div>\n<pre class=\"post-pre\"><code><span class=\"token keyword\">import<\/span> logo <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/logo.svg'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> <span class=\"token string\">'.\/App.css'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> useState<span class=\"token punctuation\">,<\/span> useEffect <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react'<\/span><span class=\"token punctuation\">;<\/span>\r\n\r\n<span class=\"token keyword\">import<\/span> <span class=\"token punctuation\">{<\/span> BrowserRouter<span class=\"token punctuation\">,<\/span> Route<span class=\"token punctuation\">,<\/span> Switch <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">from<\/span> <span class=\"token string\">'react-router-dom'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> SubscriberFeed <span class=\"token keyword\">from<\/span> <span class=\"token string\">\".\/components\/SubscriberFeed\"<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> Login <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/components\/Login'<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token keyword\">import<\/span> XSSHelper <span class=\"token keyword\">from<\/span> <span class=\"token string\">'.\/components\/XSSHelper'<\/span>\r\n\r\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">App<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n  <span class=\"token keyword\">let<\/span> <span class=\"token punctuation\">[<\/span>authenticated<span class=\"token punctuation\">,<\/span> setAuthenticated<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">useState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token keyword\">let<\/span> <span class=\"token punctuation\">[<\/span>loading<span class=\"token punctuation\">,<\/span> setLoading<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">=<\/span> <span class=\"token function\">useState<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\n  <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">getAuthStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token keyword\">await<\/span> <span class=\"token function\">setLoading<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">true<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n    <span class=\"token keyword\">return<\/span> <span class=\"token function\">fetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'http:\/\/localhost:8080\/auth-status'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span>\r\n      <span class=\"token literal-property property\">method<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'GET'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">credentials<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'include'<\/span><span class=\"token punctuation\">,<\/span>\r\n      <span class=\"token literal-property property\">headers<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span>\r\n        <span class=\"token string-property property\">'Content-Type'<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'application\/json'<\/span>\r\n      <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span>\r\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">then<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">data<\/span> <span class=\"token operator\">=&gt;<\/span> data<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span>\r\n  <span class=\"token punctuation\">}<\/span>\r\n\r\n  <span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">isAuthenticated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token keyword\">const<\/span> authStatus <span class=\"token operator\">=<\/span> <span class=\"token keyword\">await<\/span> <span class=\"token function\">getAuthStatus<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n    <span class=\"token keyword\">await<\/span> <span class=\"token function\">setAuthenticated<\/span><span class=\"token punctuation\">(<\/span>authStatus<span class=\"token punctuation\">.<\/span>isAuthenticated<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n    <span class=\"token keyword\">await<\/span> <span class=\"token function\">setLoading<\/span><span class=\"token punctuation\">(<\/span><span class=\"token boolean\">false<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token punctuation\">}<\/span>\r\n\r\n  <mark><span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">logoutUser<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n    <mark><span class=\"token keyword\">await<\/span> <span class=\"token function\">fetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">'http:\/\/localhost:8080\/logout'<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">method<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'POST'<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">credentials<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'include'<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n      <mark><span class=\"token literal-property property\">headers<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span><\/mark>\r\n        <mark><span class=\"token string-property property\">'Content-Type'<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">'application\/json'<\/span><\/mark>\r\n      <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><\/mark>\r\n    <mark><span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><\/mark>\r\n    <mark><span class=\"token function\">isAuthenticated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/mark>\r\n  <mark><span class=\"token punctuation\">}<\/span><\/mark>\r\n\r\n  <span class=\"token function\">useEffect<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">=&gt;<\/span> <span class=\"token punctuation\">{<\/span>\r\n    <span class=\"token function\">isAuthenticated<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span>\r\n\r\n  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">(<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token punctuation\">{<\/span><span class=\"token operator\">!<\/span>loading <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token punctuation\">(<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token punctuation\">{<\/span><span class=\"token operator\">!<\/span>authenticated <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token operator\">&lt;<\/span>Login <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span><span class=\"token punctuation\">}<\/span>\r\n\r\n          <span class=\"token punctuation\">{<\/span>authenticated <span class=\"token operator\">&amp;&amp;<\/span> <span class=\"token punctuation\">(<\/span>\r\n            <span class=\"token operator\">&lt;<\/span>div className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App wrapper\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n              <span class=\"token operator\">&lt;<\/span>h1 className<span class=\"token operator\">=<\/span><span class=\"token string\">\"App-header\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n                <span class=\"token constant\">JWT<\/span><span class=\"token operator\">-<\/span>Storage<span class=\"token operator\">-<\/span>Tutorial Application\r\n              <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>h1<span class=\"token operator\">&gt;<\/span>\r\n              <mark><span class=\"token operator\">&lt;<\/span>button onClick<span class=\"token operator\">=<\/span><span class=\"token punctuation\">{<\/span>logoutUser<span class=\"token punctuation\">}<\/span><span class=\"token operator\">&gt;<\/span>Logout<span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>button<span class=\"token operator\">&gt;<\/span><\/mark>\r\n              <span class=\"token operator\">&lt;<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n                <span class=\"token operator\">&lt;<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n                  <span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/subscriber-feed\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n                    <span class=\"token operator\">&lt;<\/span>SubscriberFeed <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n                  <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span>\r\n                  <span class=\"token operator\">&lt;<\/span>Route path<span class=\"token operator\">=<\/span><span class=\"token string\">\"\/xss-helper\"<\/span><span class=\"token operator\">&gt;<\/span>\r\n                    <span class=\"token operator\">&lt;<\/span>XSSHelper <span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n                  <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Route<span class=\"token operator\">&gt;<\/span>\r\n                <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>Switch<span class=\"token operator\">&gt;<\/span>\r\n              <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>BrowserRouter<span class=\"token operator\">&gt;<\/span>\r\n            <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span>div<span class=\"token operator\">&gt;<\/span>\r\n          <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">}<\/span>\r\n        <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n      <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">}<\/span>\r\n    <span class=\"token operator\">&lt;<\/span><span class=\"token operator\">\/<\/span><span class=\"token operator\">&gt;<\/span>\r\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span>\r\n<span class=\"token punctuation\">}<\/span>\r\n\r\n<span class=\"token keyword\">export<\/span> <span class=\"token keyword\">default<\/span> App<span class=\"token punctuation\">;<\/span>\r\n<\/code><\/pre>\n<p>\u4f60\u5c06\u4f1a\u521b\u5efa\u4e00\u4e2a\u201c\u767b\u51fa\u201d\u6309\u94ae\u6765\u767b\u51fa\u7528\u6237\uff0c\u5c06\u5176onClick\u5c5e\u6027\u8bbe\u7f6e\u4e3a\u4e00\u4e2a\u56de\u8c03\u51fd\u6570\uff0c\u8be5\u51fd\u6570\u4f1a\u8c03\u7528\u540e\u7aefAPI\u4e0a\u7684\u767b\u51fa\u8def\u7ebf\u3002\u8be5\u8def\u7ebf\u5c06\u4f1a\u901a\u8fc7\u8bbe\u7f6e\u4e00\u4e2aset-cookie\u5934\u6765\u5c06\u5ba2\u6237\u7aef\u7684\u4ee4\u724ccookie\u8bbe\u7f6e\u4e3anull\uff0c\u4ece\u800c\u6709\u6548\u5730\u5c06\u60a8\u7684\u524d\u7aef\u5e94\u7528\u7a0b\u5e8f\u7684\u8eab\u4efd\u9a8c\u8bc1\u72b6\u6001\u8bbe\u4e3a\u865a\u5047\u503c\u3002<\/p>\n<p>\u5728\u9000\u51fa\u56de\u8c03\u51fd\u6570\u7ed3\u675f\u65f6\uff0c\u4f60\u8fd8\u9700\u8981\u8c03\u7528isAuthenticated\u51fd\u6570\uff0c\u901a\u8fc7\u5c06authenticated\u72b6\u6001\u53d8\u91cf\u8bbe\u7f6e\u4e3afalse\u6765\u66f4\u65b0\u5e94\u7528\u7a0b\u5e8f\u7684\u72b6\u6001\uff0c\u4ee5\u53cd\u6620\u7528\u6237\u7684\u672a\u8ba4\u8bc1\u72b6\u6001\u3002<\/p>\n<p>\u5b8c\u6210\u540e\u4fdd\u5b58\u5e76\u5173\u95ed\u6587\u4ef6\u3002<\/p>\n<p>\u73b0\u5728\u4f60\u53ef\u4ee5\u6d4b\u8bd5\u57fa\u4e8e HTTP-only Cookie \u7684\u4ee4\u724c\u5b58\u50a8\u7cfb\u7edf\u3002\u5237\u65b0\u7f51\u9875\u5e94\u7528\u7a0b\u5e8f\u4ee5\u5b9e\u65bd\u521a\u521a\u6240\u505a\u7684\u4fee\u6539\u3002<\/p>\n<p>\u7136\u540e\uff0c\u6e05\u9664\u6d4f\u89c8\u5668\u5b58\u50a8\u4e2d\u7684\u5185\u5bb9\uff0c\u4ee5\u5220\u9664\u4efb\u4f55\u6b8b\u7559\u7684\u4ee4\u724c\u3002\u63a5\u4e0b\u6765\uff0c\u8bf7\u5bfc\u822a\u5230\u4e0e\u7b2c\u56db\u6b65\u4e2d\u6076\u610f\u5236\u4f5c\u7684\u76f8\u540c\u7684 URL\uff0c\u4ee5\u67e5\u770b\u653b\u51fb\u8005\u662f\u5426\u4ecd\u7136\u53ef\u4ee5\u901a\u8fc7\u6ce8\u5165\u7684 JavaScript \u6765\u7a83\u53d6\u60a8\u7684\u4ee4\u724c\u3002<\/p>\n<pre class=\"post-pre\"><code>localhost:3000\/xss-helper?code=&lt;a href=\"javascript:alert(`Your token object is ${localStorage.getItem('token')}. It has been sent to a malicious server &gt;:)`);\"&gt;Click Me!&lt;\/a&gt;\r\n<\/code><\/pre>\n<p>\u60a8\u53ef\u80fd\u9700\u8981\u91cd\u65b0\u767b\u5f55\u60a8\u7684\u7f51\u7ad9\u4ee5\u67e5\u770bXSS Helper\u6fc0\u6d3b\u7ebf\u3002\u5728\u70b9\u51fb\u540d\u4e3a\u201c\u70b9\u51fb\u6211\uff01\u201d\u7684\u94fe\u63a5\u540e\uff0c\u60a8\u5e94\u8be5\u770b\u5230\u4ee5\u4e0b\u5f39\u7a97\uff0c\u63d0\u793a\u201c\u60a8\u7684\u4ee4\u724c\u5bf9\u8c61\u4e3anull\u201d\u3002<\/p>\n<div>\n                            <img decoding=\"async\" src=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/6564666ea4b2f92e6c7266b0\/360-0.png\" class='post-images' alt=\"Screencapture of the failed XSS attack that results in \" title=\"\">\n                        <\/div>\n<p>\u6ce8\u5165\u7684JavaScript\u65e0\u6cd5\u627e\u5230\u4ee4\u724c\u5bf9\u8c61\uff0c\u56e0\u6b64\u5f39\u51fa\u7a97\u53e3\u663e\u793a\u7a7a\u503c\u3002\u5173\u95ed\u5f39\u51fa\u6d88\u606f\u3002<\/p>\n<p>\u4f60\u73b0\u5728\u53ef\u4ee5\u901a\u8fc7\u70b9\u51fb\u201c\u6ce8\u9500\u201d\u6309\u94ae\u6765\u9000\u51fa\u5e94\u7528\u3002<\/p>\n<p>\u5728\u8fd9\u4e2a\u6b65\u9aa4\u4e2d\uff0c\u4f60\u901a\u8fc7\u4ece\u4f7f\u7528\u6d4f\u89c8\u5668\u5b58\u50a8\u8fdb\u884c\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u6301\u4e45\u5316\u5207\u6362\u4e3a\u4f7f\u7528\u4ec5\u9650HTTP\u7684Cookie\u6765\u63d0\u9ad8\u4e86\u5e94\u7528\u7a0b\u5e8f\u7684\u5b89\u5168\u6027\u3002<\/p>\n<h2>\u7ed3\u8bba<\/h2>\n<p>\u5728\u672c\u6559\u7a0b\u4e2d\uff0c\u60a8\u4f7f\u7528Docker\u5bb9\u5668\u521b\u5efa\u4e86\u4e00\u4e2a\u5177\u6709\u7528\u6237\u767b\u5f55\u529f\u80fd\u7684React\u548cNode\u7f51\u9875\u5e94\u7528\u7a0b\u5e8f\u3002\u60a8\u5b9e\u65bd\u4e86\u4e00\u4e2a\u4f7f\u7528\u6613\u53d7\u653b\u51fb\u7684\u4ee4\u724c\u5b58\u50a8\u65b9\u6cd5\u7684\u8eab\u4efd\u9a8c\u8bc1\u7cfb\u7edf\uff0c\u4ee5\u6d4b\u8bd5\u60a8\u7f51\u7ad9\u7684\u5b89\u5168\u6027\u3002\u7136\u540e\uff0c\u60a8\u4f7f\u7528\u53cd\u5c04\u5f0fXSS\u653b\u51fb\u6709\u6548\u8f7d\u8377\u5229\u7528\u4e86\u8fd9\u79cd\u65b9\u6cd5\uff0c\u4ece\u800c\u4f7f\u60a8\u80fd\u591f\u8bc4\u4f30\u4f7f\u7528\u6d4f\u89c8\u5668\u5b58\u50a8\u8eab\u4efd\u9a8c\u8bc1Cookie\u65f6\u5b58\u5728\u7684\u6f0f\u6d1e\u3002\u6700\u540e\uff0c\u60a8\u901a\u8fc7\u8bbe\u7f6e\u4e00\u4e2a\u4f7f\u7528\u4ec5HTTP\u7684Cookie\u800c\u4e0d\u662f\u6d4f\u89c8\u5668\u5b58\u50a8\u6765\u5b58\u50a8\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u7684\u8eab\u4efd\u9a8c\u8bc1\u7cfb\u7edf\uff0c\u6765\u51cf\u8f7b\u521d\u59cb\u5b9e\u73b0\u4e2d\u7684XSS\u6f0f\u6d1e\u3002\u73b0\u5728\uff0c\u60a8\u62e5\u6709\u4e00\u4e2a\u57fa\u4e8eHTTP-only Cookie\u7684\u524d\u7aef\u548c\u540e\u7aef\u5e94\u7528\u7a0b\u5e8f\uff0c\u5177\u6709\u8eab\u4efd\u9a8c\u8bc1\u4ee4\u724c\u7cfb\u7edf\u3002<\/p>\n<p>\u4e3a\u4e86\u63d0\u5347\u5e94\u7528\u7a0b\u5e8f\u8ba4\u8bc1\u8fc7\u7a0b\u7684\u5b89\u5168\u6027\u548c\u6613\u7528\u6027\uff0c\u4f60\u53ef\u4ee5\u6574\u5408\u7b2c\u4e09\u65b9\u8ba4\u8bc1\u5de5\u5177\uff0c\u6bd4\u5982PassportJS\u6216\u8005\u50cfDigitalOcean\u7684OAuth API\u8fd9\u6837\u7684OAuth API\u3002\u5173\u4e8eOAuth\u6846\u67b6\u7684\u66f4\u591a\u4fe1\u606f\uff0c\u8bf7\u53c2\u8003\u300aOAuth 2\u7b80\u4ecb\u300b\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u6982\u8ff0 \u57fa\u4e8e\u4ee4\u724c\u7684\u8eab\u4efd\u9a8c\u8bc1\u53ef\u4ee5\u4fdd\u62a4\u90a3\u4e9b\u5305\u542b\u516c\u5f00\u548c\u79c1\u6709\u8d44\u6e90\u7684\u7f51\u7edc\u5e94\u7528\u3002\u8bbf\u95ee\u79c1\u6709\u8d44\u6e90\u9700\u8981\u7528\u6237\u6210\u529f\u9a8c\u8bc1\u8eab\u4efd\uff0c\u901a\u5e38\u901a\u8fc7\u63d0 [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-50669","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u5982\u4f55\u901a\u8fc7\u4f7f\u7528HTTP-Only Cookies\u6765\u4fdd\u62a4React\u5e94\u7528\u514d\u53d7XSS\u653b\u51fb - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5982\u4f55\u901a\u8fc7\u4f7f\u7528http-only-cookies\u6765\u4fdd\u62a4react\u5e94\u7528\u514d\u53d7xss\u653b\u51fb\u3002\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u5982\u4f55\u901a\u8fc7\u4f7f\u7528HTTP-Only Cookies\u6765\u4fdd\u62a4React\u5e94\u7528\u514d\u53d7XSS\u653b\u51fb\" \/>\n<meta property=\"og:description\" content=\"\u6982\u8ff0 \u57fa\u4e8e\u4ee4\u724c\u7684\u8eab\u4efd\u9a8c\u8bc1\u53ef\u4ee5\u4fdd\u62a4\u90a3\u4e9b\u5305\u542b\u516c\u5f00\u548c\u79c1\u6709\u8d44\u6e90\u7684\u7f51\u7edc\u5e94\u7528\u3002\u8bbf\u95ee\u79c1\u6709\u8d44\u6e90\u9700\u8981\u7528\u6237\u6210\u529f\u9a8c\u8bc1\u8eab\u4efd\uff0c\u901a\u5e38\u901a\u8fc7\u63d0 [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5982\u4f55\u901a\u8fc7\u4f7f\u7528http-only-cookies\u6765\u4fdd\u62a4react\u5e94\u7528\u514d\u53d7xss\u653b\u51fb\u3002\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2023-12-22T06:47:14+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-12-25T08:57:46+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/6564666ea4b2f92e6c7266b0\/74-0.png\" \/>\n<meta name=\"author\" content=\"\u6587, \u7fd4\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u6587, \u7fd4\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/\",\"name\":\"\u5982\u4f55\u901a\u8fc7\u4f7f\u7528HTTP-Only Cookies\u6765\u4fdd\u62a4React\u5e94\u7528\u514d\u53d7XSS\u653b\u51fb - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2023-12-22T06:47:14+00:00\",\"dateModified\":\"2023-12-25T08:57:46+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/64d5cc7727fffbff2f9a2a8da1de3e5c\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u5982\u4f55\u901a\u8fc7\u4f7f\u7528HTTP-Only Cookies\u6765\u4fdd\u62a4React\u5e94\u7528\u514d\u53d7XSS\u653b\u51fb\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/64d5cc7727fffbff2f9a2a8da1de3e5c\",\"name\":\"\u6587, \u7fd4\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/920c3d673e0bccacc98e5e6b7149bb3c22edd8d39cb753e5d7d7e471498118a1?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/920c3d673e0bccacc98e5e6b7149bb3c22edd8d39cb753e5d7d7e471498118a1?s=96&d=mm&r=g\",\"caption\":\"\u6587, \u7fd4\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/wenxiang\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u5982\u4f55\u901a\u8fc7\u4f7f\u7528HTTP-Only Cookies\u6765\u4fdd\u62a4React\u5e94\u7528\u514d\u53d7XSS\u653b\u51fb - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u5982\u4f55\u901a\u8fc7\u4f7f\u7528http-only-cookies\u6765\u4fdd\u62a4react\u5e94\u7528\u514d\u53d7xss\u653b\u51fb\u3002\/","og_locale":"zh_CN","og_type":"article","og_title":"\u5982\u4f55\u901a\u8fc7\u4f7f\u7528HTTP-Only Cookies\u6765\u4fdd\u62a4React\u5e94\u7528\u514d\u53d7XSS\u653b\u51fb","og_description":"\u6982\u8ff0 \u57fa\u4e8e\u4ee4\u724c\u7684\u8eab\u4efd\u9a8c\u8bc1\u53ef\u4ee5\u4fdd\u62a4\u90a3\u4e9b\u5305\u542b\u516c\u5f00\u548c\u79c1\u6709\u8d44\u6e90\u7684\u7f51\u7edc\u5e94\u7528\u3002\u8bbf\u95ee\u79c1\u6709\u8d44\u6e90\u9700\u8981\u7528\u6237\u6210\u529f\u9a8c\u8bc1\u8eab\u4efd\uff0c\u901a\u5e38\u901a\u8fc7\u63d0 [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u5982\u4f55\u901a\u8fc7\u4f7f\u7528http-only-cookies\u6765\u4fdd\u62a4react\u5e94\u7528\u514d\u53d7xss\u653b\u51fb\u3002\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2023-12-22T06:47:14+00:00","article_modified_time":"2023-12-25T08:57:46+00:00","og_image":[{"url":"https:\/\/cdn.silicloud.com\/blog-img\/blog\/img\/6564666ea4b2f92e6c7266b0\/74-0.png"}],"author":"\u6587, \u7fd4","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u6587, \u7fd4","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"4 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/","name":"\u5982\u4f55\u901a\u8fc7\u4f7f\u7528HTTP-Only Cookies\u6765\u4fdd\u62a4React\u5e94\u7528\u514d\u53d7XSS\u653b\u51fb - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2023-12-22T06:47:14+00:00","dateModified":"2023-12-25T08:57:46+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/64d5cc7727fffbff2f9a2a8da1de3e5c"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u5982\u4f55\u901a\u8fc7\u4f7f\u7528HTTP-Only Cookies\u6765\u4fdd\u62a4React\u5e94\u7528\u514d\u53d7XSS\u653b\u51fb"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/64d5cc7727fffbff2f9a2a8da1de3e5c","name":"\u6587, \u7fd4","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/920c3d673e0bccacc98e5e6b7149bb3c22edd8d39cb753e5d7d7e471498118a1?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/920c3d673e0bccacc98e5e6b7149bb3c22edd8d39cb753e5d7d7e471498118a1?s=96&d=mm&r=g","caption":"\u6587, \u7fd4"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/wenxiang\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%a6%82%e4%bd%95%e9%80%9a%e8%bf%87%e4%bd%bf%e7%94%a8http-only-cookies%e6%9d%a5%e4%bf%9d%e6%8a%a4react%e5%ba%94%e7%94%a8%e5%85%8d%e5%8f%97xss%e6%94%bb%e5%87%bb%e3%80%82\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/50669","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=50669"}],"version-history":[{"count":6,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/50669\/revisions"}],"predecessor-version":[{"id":50820,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/50669\/revisions\/50820"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=50669"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=50669"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=50669"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}