{"id":16547,"date":"2024-01-26T19:42:58","date_gmt":"2024-01-26T16:12:58","guid":{"rendered":"https:\/\/rasanegar.com\/blog\/%d8%a8%d8%b1%d9%86%d8%a7%d9%85%d9%87-%d9%87%d8%a7%db%8c-%d8%aa%da%a9-%d8%b5%d9%81%d8%ad%d9%87-%d8%a7%db%8c-%d8%a8%d8%a7-vue-js-%d9%88-flask-jwt-authentication-%d8%a8%d9%87-%d9%82%d8%b3%d9%85%d8%aa\/"},"modified":"2024-01-26T19:42:58","modified_gmt":"2024-01-26T16:12:58","slug":"%d8%a8%d8%b1%d9%86%d8%a7%d9%85%d9%87-%d9%87%d8%a7%db%8c-%d8%aa%da%a9-%d8%b5%d9%81%d8%ad%d9%87-%d8%a7%db%8c-%d8%a8%d8%a7-vue-js-%d9%88-flask-jwt-authentication-%d8%a8%d9%87-%d9%82%d8%b3%d9%85%d8%aa","status":"publish","type":"post","link":"https:\/\/rasanegaar.com\/blog\/%d8%a8%d8%b1%d9%86%d8%a7%d9%85%d9%87-%d9%87%d8%a7%db%8c-%d8%aa%da%a9-%d8%b5%d9%81%d8%ad%d9%87-%d8%a7%db%8c-%d8%a8%d8%a7-vue-js-%d9%88-flask-jwt-authentication-%d8%a8%d9%87-%d9%82%d8%b3%d9%85%d8%aa\/","title":{"rendered":"\u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc \u062a\u06a9 \u0635\u0641\u062d\u0647 \u0627\u06cc \u0628\u0627 Vue.js \u0648 Flask: JWT Authentication \u0628\u0647 \u0642\u0633\u0645\u062a \u0634\u0634\u0645 \u0627\u06cc\u0646 \u0645\u062c\u0645\u0648\u0639\u0647 \u0622\u0645\u0648\u0632\u0634\u06cc \u0686\u0646\u062f \u0642\u0633\u0645\u062a\u06cc \u062e\u0648\u0634 \u0622\u0645\u062f\u06cc\u062f \u0631\u0648\u06cc \u062a\u0648\u0633\u0639\u0647 \u0648\u0628 \u062a\u0645\u0627\u0645 \u067e\u0634\u062a\u0647 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Vue.js \u0648 Flask.  \u062f\u0631 \u0627\u06cc\u0646 \u067e\u0633\u062a \u0645\u0646 \u0631\u0648\u0634\u06cc \u0628\u0631\u0627\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 JSON Web Token (JWT) \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0631\u0627 \u0646\u0634\u0627\u0646 \u062e\u0648\u0627\u0647\u0645 \u062f\u0627\u062f.  \u06a9\u062f \u0627\u06cc\u0646 \u067e\u0633\u062a \u0631\u0627 \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u067e\u06cc\u062f\u0627 \u06a9\u0646\u06cc\u062f \u0631\u0648\u06cc \u062d\u0633\u0627\u0628 GitHub \u0645\u0646 \u062f\u0631 \u0632\u06cc\u0631 \u0634\u0627\u062e\u0647 &#8230;"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\"><p class=\"ez-toc-title\" style=\"cursor:inherit\">\u0633\u0631\u0641\u0635\u0644\u0647\u0627\u06cc \u0645\u0637\u0644\u0628<\/p>\n<\/div><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/rasanegaar.com\/blog\/%d8%a8%d8%b1%d9%86%d8%a7%d9%85%d9%87-%d9%87%d8%a7%db%8c-%d8%aa%da%a9-%d8%b5%d9%81%d8%ad%d9%87-%d8%a7%db%8c-%d8%a8%d8%a7-vue-js-%d9%88-flask-jwt-authentication-%d8%a8%d9%87-%d9%82%d8%b3%d9%85%d8%aa\/#%d8%a7%d8%ad%d8%b1%d8%a7%d8%b2_%d9%87%d9%88%db%8c%d8%aa_jwt\" >\u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a JWT<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/rasanegaar.com\/blog\/%d8%a8%d8%b1%d9%86%d8%a7%d9%85%d9%87-%d9%87%d8%a7%db%8c-%d8%aa%da%a9-%d8%b5%d9%81%d8%ad%d9%87-%d8%a7%db%8c-%d8%a8%d8%a7-vue-js-%d9%88-flask-jwt-authentication-%d8%a8%d9%87-%d9%82%d8%b3%d9%85%d8%aa\/#%d9%85%d8%ad%d8%aa%d9%88%d8%a7%db%8c_%d8%b3%d8%b1%db%8c\" >\u0645\u062d\u062a\u0648\u0627\u06cc \u0633\u0631\u06cc<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/rasanegaar.com\/blog\/%d8%a8%d8%b1%d9%86%d8%a7%d9%85%d9%87-%d9%87%d8%a7%db%8c-%d8%aa%da%a9-%d8%b5%d9%81%d8%ad%d9%87-%d8%a7%db%8c-%d8%a8%d8%a7-vue-js-%d9%88-flask-jwt-authentication-%d8%a8%d9%87-%d9%82%d8%b3%d9%85%d8%aa\/#%d9%85%d9%82%d8%af%d9%85%d9%87_%d8%a7%d9%88%d9%84%db%8c%d9%87_%d8%a7%d8%ad%d8%b1%d8%a7%d8%b2_%d9%87%d9%88%db%8c%d8%aa_jwt\" >\u0645\u0642\u062f\u0645\u0647 \u0627\u0648\u0644\u06cc\u0647 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a JWT<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/rasanegaar.com\/blog\/%d8%a8%d8%b1%d9%86%d8%a7%d9%85%d9%87-%d9%87%d8%a7%db%8c-%d8%aa%da%a9-%d8%b5%d9%81%d8%ad%d9%87-%d8%a7%db%8c-%d8%a8%d8%a7-vue-js-%d9%88-flask-jwt-authentication-%d8%a8%d9%87-%d9%82%d8%b3%d9%85%d8%aa\/#%d9%be%db%8c%d8%a7%d8%af%d9%87_%d8%b3%d8%a7%d8%b2%db%8c_jwt_authentication_%d8%af%d8%b1_flask_restful_api\" >\u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc JWT Authentication \u062f\u0631 Flask RESTful API<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/rasanegaar.com\/blog\/%d8%a8%d8%b1%d9%86%d8%a7%d9%85%d9%87-%d9%87%d8%a7%db%8c-%d8%aa%da%a9-%d8%b5%d9%81%d8%ad%d9%87-%d8%a7%db%8c-%d8%a8%d8%a7-vue-js-%d9%88-flask-jwt-authentication-%d8%a8%d9%87-%d9%82%d8%b3%d9%85%d8%aa\/#%d9%be%db%8c%d8%a7%d8%af%d9%87_%d8%b3%d8%a7%d8%b2%db%8c_jwt_authentication_%d8%af%d8%b1_vuejs_spa\" >\u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc JWT Authentication \u062f\u0631 Vue.js SPA<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/rasanegaar.com\/blog\/%d8%a8%d8%b1%d9%86%d8%a7%d9%85%d9%87-%d9%87%d8%a7%db%8c-%d8%aa%da%a9-%d8%b5%d9%81%d8%ad%d9%87-%d8%a7%db%8c-%d8%a8%d8%a7-vue-js-%d9%88-flask-jwt-authentication-%d8%a8%d9%87-%d9%82%d8%b3%d9%85%d8%aa\/#%d9%85%d9%86%d8%a7%d8%a8%d8%b9\" >\u0645\u0646\u0627\u0628\u0639<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/rasanegaar.com\/blog\/%d8%a8%d8%b1%d9%86%d8%a7%d9%85%d9%87-%d9%87%d8%a7%db%8c-%d8%aa%da%a9-%d8%b5%d9%81%d8%ad%d9%87-%d8%a7%db%8c-%d8%a8%d8%a7-vue-js-%d9%88-flask-jwt-authentication-%d8%a8%d9%87-%d9%82%d8%b3%d9%85%d8%aa\/#%d9%86%d8%aa%db%8c%d8%ac%d9%87\" >\u0646\u062a\u06cc\u062c\u0647<\/a><\/li><\/ul><\/nav><\/div>\n<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">\u0632\u0645\u0627\u0646 \u0644\u0627\u0632\u0645 \u0628\u0631\u0627\u06cc \u0645\u0637\u0627\u0644\u0639\u0647: <\/span> <span class=\"rt-time\"> 15<\/span> <span class=\"rt-label rt-postfix\">\u062f\u0642\u06cc\u0642\u0647<\/span><\/span><p> <br \/>\n<\/p>\n<div class=\"content\"><noscript><\/p>\n<style>.lazyload-placeholder { display: none;  }<\/style>\n<p><\/noscript><\/p>\n<h2 id=\"jwtauthentication\"><span class=\"ez-toc-section\" id=\"%d8%a7%d8%ad%d8%b1%d8%a7%d8%b2_%d9%87%d9%88%db%8c%d8%aa_jwt\"><\/span>\u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a JWT<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0628\u0647 \u0642\u0633\u0645\u062a \u0634\u0634\u0645 \u0627\u06cc\u0646 \u0645\u062c\u0645\u0648\u0639\u0647 \u0622\u0645\u0648\u0632\u0634\u06cc \u0686\u0646\u062f \u0642\u0633\u0645\u062a\u06cc \u062e\u0648\u0634 \u0622\u0645\u062f\u06cc\u062f \u0631\u0648\u06cc \u062a\u0648\u0633\u0639\u0647 \u0648\u0628 \u062a\u0645\u0627\u0645 \u067e\u0634\u062a\u0647 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Vue.js \u0648 Flask.  \u062f\u0631 \u0627\u06cc\u0646 \u067e\u0633\u062a \u0645\u0646 \u0631\u0648\u0634\u06cc \u0628\u0631\u0627\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 JSON Web Token (JWT) \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0631\u0627 \u0646\u0634\u0627\u0646 \u062e\u0648\u0627\u0647\u0645 \u062f\u0627\u062f.<\/p>\n<p>\u06a9\u062f \u0627\u06cc\u0646 \u067e\u0633\u062a \u0631\u0627 \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u067e\u06cc\u062f\u0627 \u06a9\u0646\u06cc\u062f \u0631\u0648\u06cc \u062d\u0633\u0627\u0628 GitHub \u0645\u0646 \u062f\u0631 \u0632\u06cc\u0631 \u0634\u0627\u062e\u0647 <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/amcquistan\/flask-vuejs-survey\/tree\/SixthPost\">\u067e\u0633\u062a \u0634\u0634\u0645<\/a>.<\/p>\n<h2 id=\"seriescontent\"><span class=\"ez-toc-section\" id=\"%d9%85%d8%ad%d8%aa%d9%88%d8%a7%db%8c_%d8%b3%d8%b1%db%8c\"><\/span>\u0645\u062d\u062a\u0648\u0627\u06cc \u0633\u0631\u06cc<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ol>\n<li>\u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc \u0648 \u0622\u0634\u0646\u0627\u06cc\u06cc \u0628\u0627 VueJS<\/li>\n<li>\u0645\u0633\u06cc\u0631\u06cc\u0627\u0628 Vue<\/li>\n<li>\u0645\u062f\u06cc\u0631\u06cc\u062a \u062f\u0648\u0644\u062a\u06cc \u0628\u0627 Vuex<\/li>\n<li>RESTful API \u0628\u0627 Flask<\/li>\n<li>\u0627\u062f\u063a\u0627\u0645 AJAX \u0628\u0627 REST API<\/li>\n<li>\u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a JWT <em>(\u062a\u0648 \u0627\u06cc\u0646\u062c\u0627\u06cc\u06cc)<\/em><\/li>\n<li>\u0627\u0633\u062a\u0642\u0631\u0627\u0631 \u062f\u0631 \u06cc\u06a9 \u0633\u0631\u0648\u0631 \u062e\u0635\u0648\u0635\u06cc \u0645\u062c\u0627\u0632\u06cc<\/li>\n<\/ol>\n<h2 id=\"basicintroductiontojwtauthentication\"><span class=\"ez-toc-section\" id=\"%d9%85%d9%82%d8%af%d9%85%d9%87_%d8%a7%d9%88%d9%84%db%8c%d9%87_%d8%a7%d8%ad%d8%b1%d8%a7%d8%b2_%d9%87%d9%88%db%8c%d8%aa_jwt\"><\/span>\u0645\u0642\u062f\u0645\u0647 \u0627\u0648\u0644\u06cc\u0647 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a JWT<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0645\u0634\u0627\u0628\u0647 \u0628\u0631\u062e\u06cc \u0627\u0632 \u067e\u0633\u062a \u0647\u0627\u06cc \u062f\u06cc\u06af\u0631 \u062f\u0631 \u0627\u06cc\u0646 \u0645\u062c\u0645\u0648\u0639\u0647\u060c \u0645\u0646 \u0648\u0627\u0631\u062f \u062c\u0632\u0626\u06cc\u0627\u062a \u0645\u0647\u0645 \u0646\u0645\u06cc \u0634\u0648\u0645 \u0631\u0648\u06cc \u0646\u0638\u0631\u06cc\u0647 \u0686\u06af\u0648\u0646\u06af\u06cc <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/JSON_Web_Token\">JWT<\/a> \u0622\u062b\u0627\u0631.  \u062f\u0631 \u0639\u0648\u0636\u060c \u0645\u0646 \u06cc\u06a9 \u0631\u0648\u06cc\u06a9\u0631\u062f \u0639\u0645\u0644\u06af\u0631\u0627\u06cc\u0627\u0646\u0647 \u0631\u0627 \u062f\u0631 \u067e\u06cc\u0634 \u062e\u0648\u0627\u0647\u0645 \u06af\u0631\u0641\u062a \u0648 \u0648\u06cc\u0698\u06af\u06cc \u0647\u0627\u06cc \u0627\u062c\u0631\u0627\u06cc \u0622\u0646 \u0631\u0627 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0641\u0646\u0627\u0648\u0631\u06cc \u0647\u0627\u06cc \u0645\u0648\u0631\u062f \u0639\u0644\u0627\u0642\u0647 \u062f\u0631 Flask \u0648 Vue.js \u0646\u0634\u0627\u0646 \u062e\u0648\u0627\u0647\u0645 \u062f\u0627\u062f.  \u0627\u06af\u0631 \u0639\u0644\u0627\u0642\u0647 \u0645\u0646\u062f \u0628\u0647 \u062f\u0631\u06a9 \u0639\u0645\u06cc\u0642 \u062a\u0631 \u0627\u0632 JWT \u0647\u0633\u062a\u06cc\u062f\u060c \u0634\u0645\u0627 \u0631\u0627 \u0628\u0647 \u067e\u0633\u062a \u0639\u0627\u0644\u06cc \u0627\u0633\u06a9\u0627\u062a \u0631\u0627\u0628\u06cc\u0646\u0633\u0648\u0646 \u062f\u0631 \u0627\u06cc\u0646\u062c\u0627 \u0627\u0631\u062c\u0627\u0639 \u0645\u06cc \u062f\u0647\u0645. \u0631\u0648\u06cc rasanegar\u060c \u062c\u0627\u06cc\u06cc \u06a9\u0647 \u0627\u0648 \u062c\u0632\u0626\u06cc\u0627\u062a \u0633\u0637\u062d \u067e\u0627\u06cc\u06cc\u0646 \u0627\u06cc\u0646 \u062a\u06a9\u0646\u06cc\u06a9 \u0631\u0627 \u062a\u0648\u0636\u06cc\u062d \u0645\u06cc \u062f\u0647\u062f.<\/p>\n<p>\u062f\u0631 \u0645\u0641\u0647\u0648\u0645 \u0627\u0633\u0627\u0633\u06cc \u06cc\u06a9 JWT \u06cc\u06a9 \u0634\u06cc JSON \u06a9\u062f\u06af\u0630\u0627\u0631\u06cc \u0634\u062f\u0647 \u0627\u0633\u062a \u06a9\u0647 \u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0642\u0627\u0644 \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0628\u06cc\u0646 \u062f\u0648 \u0633\u06cc\u0633\u062a\u0645 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f \u06a9\u0647 \u0627\u0632 \u06cc\u06a9 \u0647\u062f\u0631\u060c \u06cc\u06a9 \u0628\u0627\u0631 \u0648 \u06cc\u06a9 \u0627\u0645\u0636\u0627 \u0628\u0647 \u0634\u06a9\u0644 \u0632\u06cc\u0631 \u062a\u0634\u06a9\u06cc\u0644 \u0634\u062f\u0647 \u0627\u0633\u062a. <code>(HEADER).(PAYLOAD).(SIGNATURE)<\/code> \u0647\u0645\u0647 \u062f\u0631 \u0647\u062f\u0631 HTTP \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 &#8220;Authorization: Bearer (HEADER).(PAYLOAD).(SIGNATURE)&#8221; \u0645\u0648\u062c\u0648\u062f \u0627\u0633\u062a.  \u0627\u06cc\u0646 process \u0628\u0627 \u062a\u0623\u06cc\u06cc\u062f \u0627\u0639\u062a\u0628\u0627\u0631 \u0645\u0634\u062a\u0631\u06cc (\u0633\u06cc\u0633\u062a\u0645 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u06a9\u0646\u0646\u062f\u0647) \u0628\u0627 \u0633\u0631\u0648\u0631 (\u0633\u0631\u0648\u06cc\u0633 \u0628\u0627 \u0645\u0646\u0628\u0639 \u0645\u0648\u0631\u062f \u0646\u0638\u0631) \u0634\u0631\u0648\u0639 \u0645\u06cc \u0634\u0648\u062f \u06a9\u0647 \u06cc\u06a9 JWT \u062a\u0648\u0644\u06cc\u062f \u0645\u06cc \u06a9\u0646\u062f \u06a9\u0647 \u0641\u0642\u0637 \u0628\u0631\u0627\u06cc \u0645\u062f\u062a \u0632\u0645\u0627\u0646 \u0645\u0634\u062e\u0635\u06cc \u0645\u0639\u062a\u0628\u0631 \u0627\u0633\u062a.  \u0633\u067e\u0633 \u0633\u0631\u0648\u0631 \u0627\u06cc\u0646 \u0631\u0627 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u06cc\u06a9 \u0631\u0645\u0632 \u0627\u0645\u0636\u0627 \u0634\u062f\u0647 \u0648 \u0631\u0645\u0632\u06af\u0630\u0627\u0631\u06cc \u0634\u062f\u0647 \u0628\u0631\u0627\u06cc \u0645\u0634\u062a\u0631\u06cc \u0628\u0631\u0645\u06cc \u06af\u0631\u062f\u0627\u0646\u062f \u062a\u0627 \u0622\u0646 \u0631\u0627 \u0630\u062e\u06cc\u0631\u0647 \u06a9\u0631\u062f\u0647 \u0648 \u0628\u0631\u0627\u06cc \u062a\u0623\u06cc\u06cc\u062f \u062f\u0631 \u0627\u0631\u062a\u0628\u0627\u0637\u0627\u062a \u0628\u0639\u062f\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u062f.<\/p>\n<p>\u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a JWT \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0647\u0627\u06cc SPA \u0645\u0627\u0646\u0646\u062f \u0628\u0631\u0646\u0627\u0645\u0647\u200c\u0627\u06cc \u06a9\u0647 \u062f\u0631 \u0627\u06cc\u0646 \u0633\u0631\u06cc \u0633\u0627\u062e\u062a\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a\u060c \u0628\u0633\u06cc\u0627\u0631 \u062e\u0648\u0628 \u0639\u0645\u0644 \u0645\u06cc\u200c\u06a9\u0646\u062f \u0648 \u0645\u062d\u0628\u0648\u0628\u06cc\u062a \u0642\u0627\u0628\u0644 \u062a\u0648\u062c\u0647\u06cc \u062f\u0631 \u0645\u06cc\u0627\u0646 \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u06af\u0627\u0646\u06cc \u06a9\u0647 \u0622\u0646\u200c\u0647\u0627 \u0631\u0627 \u067e\u06cc\u0627\u062f\u0647\u200c\u0633\u0627\u0632\u06cc \u0645\u06cc\u200c\u06a9\u0646\u0646\u062f\u060c \u0628\u0647 \u062f\u0633\u062a \u0622\u0648\u0631\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<h2 id=\"implementingjwtauthenticationintheflaskrestfulapi\"><span class=\"ez-toc-section\" id=\"%d9%be%db%8c%d8%a7%d8%af%d9%87_%d8%b3%d8%a7%d8%b2%db%8c_jwt_authentication_%d8%af%d8%b1_flask_restful_api\"><\/span>\u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc JWT Authentication \u062f\u0631 Flask RESTful API<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u062f\u0631 \u0633\u0645\u062a Flask \u0686\u06cc\u0632\u0647\u0627\u060c \u0645\u0646 \u0627\u0632 \u0628\u0633\u062a\u0647 \u067e\u0627\u06cc\u062a\u0648\u0646 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062e\u0648\u0627\u0647\u0645 \u06a9\u0631\u062f <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/jpadilla\/pyjwt\">PyJWT<\/a> \u0628\u0631\u0627\u06cc \u0631\u0633\u06cc\u062f\u06af\u06cc \u0628\u0647 \u0628\u0631\u062e\u06cc \u0627\u0632 \u062c\u0632\u0626\u06cc\u0627\u062a \u067e\u06cc\u0631\u0627\u0645\u0648\u0646 \u0627\u06cc\u062c\u0627\u062f\u060c \u062a\u062c\u0632\u06cc\u0647 \u0648 \u0627\u0639\u062a\u0628\u0627\u0631\u0633\u0646\u062c\u06cc JWT \u0647\u0627.<\/p>\n<pre><code class=\"hljs\">(venv) $ pip install PyJWT\n<\/code><\/pre>\n<p>\u0628\u0627 \u0646\u0635\u0628 \u0628\u0633\u062a\u0647 PyJWT \u0645\u06cc \u062a\u0648\u0627\u0646\u0645 \u062d\u0631\u06a9\u062a \u06a9\u0646\u0645 \u0631\u0648\u06cc \u0628\u0631\u0627\u06cc \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u0642\u0637\u0639\u0627\u062a \u0644\u0627\u0632\u0645 \u0628\u0631\u0627\u06cc \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0648 \u062a\u0623\u06cc\u06cc\u062f \u062f\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 Flask.  \u0628\u0631\u0627\u06cc \u0634\u0631\u0648\u0639\u060c \u0645\u0646 \u0628\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u06cc\u0646 \u0627\u0645\u06a9\u0627\u0646 \u0631\u0627 \u0645\u06cc \u062f\u0647\u0645 \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u062b\u0628\u062a \u0646\u0627\u0645 \u0634\u062f\u0647 \u062c\u062f\u06cc\u062f\u06cc \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u062f \u06a9\u0647 \u0628\u0627 a \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u0646\u062f <code>User<\/code> \u06a9\u0644\u0627\u0633  \u0645\u0627\u0646\u0646\u062f \u062a\u0645\u0627\u0645 \u06a9\u0644\u0627\u0633 \u0647\u0627\u06cc \u062f\u06cc\u06af\u0631 \u062f\u0631 \u0627\u06cc\u0646 \u0628\u0631\u0646\u0627\u0645\u0647 <code>User<\/code> \u06a9\u0644\u0627\u0633 \u0633\u0627\u06a9\u0646 \u062e\u0648\u0627\u0647\u062f \u0634\u062f <code>models.py<\/code> \u0645\u062f\u0648\u0644.<\/p>\n<p>\u0627\u0648\u0644\u06cc\u0646 \u0645\u0648\u0631\u062f\u06cc \u06a9\u0647 \u0628\u0627\u06cc\u062f \u0627\u0646\u062c\u0627\u0645 \u062f\u0627\u062f \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 import \u0686\u0646\u062f \u062a\u0627\u0628\u0639\u060c <code>generate_password_hash<\/code> \u0648 <code>check_password_hash<\/code> \u0627\u0632 <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/pallets\/werkzeug\">werkzeug<\/a> \u0628\u0633\u062a\u0647 \u0647\u0627 <code>security<\/code> \u0645\u0627\u0698\u0648\u0644\u06cc \u06a9\u0647 \u0645\u0646 \u0627\u0632 \u0622\u0646 \u0628\u0631\u0627\u06cc \u062a\u0648\u0644\u06cc\u062f \u0648 \u062a\u0623\u06cc\u06cc\u062f \u0631\u0645\u0632\u0647\u0627\u06cc \u0639\u0628\u0648\u0631 \u0647\u0634 \u0634\u062f\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062e\u0648\u0627\u0647\u0645 \u06a9\u0631\u062f.  \u0646\u06cc\u0627\u0632\u06cc \u0628\u0647 \u0646\u0635\u0628 \u0627\u06cc\u0646 \u0628\u0633\u062a\u0647 \u0646\u06cc\u0633\u062a \u0632\u06cc\u0631\u0627 \u0628\u0627 Flask \u0628\u0647 \u0635\u0648\u0631\u062a \u062e\u0648\u062f\u06a9\u0627\u0631 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc \u0634\u0648\u062f.<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"\"\"\nmodels.py\n- Data classes for the surveyapi application\n\"\"\"<\/span>\n\n<span class=\"hljs-keyword\">from<\/span> datetime <span class=\"hljs-keyword\">import<\/span> datetime\n<span class=\"hljs-keyword\">from<\/span> flask_sqlalchemy <span class=\"hljs-keyword\">import<\/span> SQLAlchemy\n\n<span class=\"hljs-keyword\">from<\/span> werkzeug.security <span class=\"hljs-keyword\">import<\/span> generate_password_hash, check_password_hash\n\ndb = SQLAlchemy()\n<\/code><\/pre>\n<p>\u0645\u0633\u062a\u0642\u06cc\u0645\u0627\u064b \u062f\u0631 \u0632\u06cc\u0631 \u06a9\u062f \u0628\u0627\u0644\u0627 \u062a\u0639\u0631\u06cc\u0641 \u0645\u06cc \u06a9\u0646\u0645 <code>User<\/code> \u06a9\u0644\u0627\u0633\u060c \u06a9\u0647 \u0627\u0632 SQLAlchemy \u0628\u0647 \u0627\u0631\u062b \u0645\u06cc \u0628\u0631\u062f <code>Model<\/code> \u06a9\u0644\u0627\u0633 \u0645\u0634\u0627\u0628\u0647 \u0633\u0627\u06cc\u0631 \u0645\u0648\u0627\u0631\u062f\u06cc \u0627\u0633\u062a \u06a9\u0647 \u062f\u0631 \u067e\u0633\u062a \u0647\u0627\u06cc \u0642\u0628\u0644\u06cc \u062a\u0639\u0631\u06cc\u0641 \u0634\u062f\u0647 \u0627\u0633\u062a.  \u0627\u06cc\u0646 <code>User<\/code> \u06a9\u0644\u0627\u0633 \u0628\u0627\u06cc\u062f \u062d\u0627\u0648\u06cc \u06cc\u06a9 \u0641\u06cc\u0644\u062f \u06a9\u0644\u0627\u0633 \u06a9\u0644\u06cc\u062f \u0627\u0648\u0644\u06cc\u0647 \u0627\u0639\u062f\u0627\u062f \u0635\u062d\u06cc\u062d \u062a\u0648\u0644\u06cc\u062f \u0634\u062f\u0647 \u062e\u0648\u062f\u06a9\u0627\u0631 \u0628\u0647 \u0646\u0627\u0645 \u0628\u0627\u0634\u062f <code>id<\/code> \u0633\u067e\u0633 \u062f\u0648 \u0641\u06cc\u0644\u062f \u0631\u0634\u062a\u0647 \u0627\u06cc \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u0634\u062f <code>email<\/code> \u0648 <code>password<\/code> \u0628\u0627 \u0627\u06cc\u0645\u06cc\u0644\u06cc \u06a9\u0647 \u0628\u0631\u0627\u06cc \u0645\u0646\u062d\u0635\u0631 \u0628\u0647 \u0641\u0631\u062f \u0628\u0648\u062f\u0646 \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc \u0634\u062f\u0647 \u0627\u0633\u062a.  \u0645\u0646 \u0647\u0645 \u0628\u0647 \u0627\u06cc\u0646 \u06a9\u0644\u0627\u0633 a \u0645\u06cc \u062f\u0647\u0645 <code>relationship<\/code> \u0632\u0645\u06cc\u0646\u0647 \u0628\u0631\u0627\u06cc \u0645\u0631\u062a\u0628\u0637 \u06a9\u0631\u062f\u0646 \u0647\u0631 \u0646\u0638\u0631\u0633\u0646\u062c\u06cc \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u0645\u0645\u06a9\u0646 \u0627\u0633\u062a \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u062f.  \u062f\u0631 \u0637\u0631\u0641 \u062f\u06cc\u06af\u0631 \u0627\u06cc\u0646 \u0645\u0639\u0627\u062f\u0644\u0647 a \u0631\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u0645 <code>creator_id<\/code> \u06a9\u0644\u06cc\u062f \u062e\u0627\u0631\u062c\u06cc \u0628\u0647 <code>Survey<\/code> \u06a9\u0644\u0627\u0633 \u0628\u0631\u0627\u06cc \u067e\u06cc\u0648\u0646\u062f \u062f\u0627\u062f\u0646 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0628\u0647 \u0646\u0638\u0631\u0633\u0646\u062c\u06cc \u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u0646\u062f.<\/p>\n<p>\u0645\u0646 \u0631\u062f \u0645\u06cc \u06a9\u0646\u0645 <code>__init__(...)<\/code> \u0631\u0648\u0634\u06cc \u0628\u0631\u0627\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0628\u062a\u0648\u0627\u0646\u0645 \u067e\u0633\u0648\u0631\u062f \u0631\u0627 \u067e\u0633 \u0627\u0632 \u0627\u06cc\u062c\u0627\u062f \u06cc\u06a9 \u0631\u0645\u0632 \u0639\u0628\u0648\u0631 \u062c\u062f\u06cc\u062f \u0647\u0634 \u06a9\u0646\u0645 <code>User<\/code> \u0647\u062f\u0641 &#8211; \u0634\u06cc.  \u067e\u0633 \u0627\u0632 \u0622\u0646 \u0645\u0646 \u0628\u0647 \u0622\u0646 \u0645\u062a\u062f \u06a9\u0644\u0627\u0633 \u0645\u06cc \u062f\u0647\u0645\u060c <code>authenticate<\/code>\u060c \u0628\u0631\u0627\u06cc \u067e\u0631\u0633 \u0648 \u062c\u0648 \u0627\u0632 \u06a9\u0627\u0631\u0628\u0631 \u0627\u0632 \u0637\u0631\u06cc\u0642 \u0627\u06cc\u0645\u06cc\u0644 \u0648 \u0628\u0631\u0631\u0633\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0647\u0634 \u0631\u0645\u0632 \u0639\u0628\u0648\u0631 \u0627\u0631\u0627\u0626\u0647 \u0634\u062f\u0647 \u0628\u0627 \u0631\u0645\u0632 \u0630\u062e\u06cc\u0631\u0647 \u0634\u062f\u0647 \u062f\u0631 \u067e\u0627\u06cc\u06af\u0627\u0647 \u062f\u0627\u062f\u0647 \u0645\u0637\u0627\u0628\u0642\u062a \u062f\u0627\u0631\u062f.  \u0627\u06af\u0631 \u0645\u0637\u0627\u0628\u0642\u062a \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0646\u062f\u060c \u06a9\u0627\u0631\u0628\u0631 \u062a\u0623\u06cc\u06cc\u062f \u0634\u062f\u0647 \u0631\u0627 \u0628\u0631\u0645\u06cc \u06af\u0631\u062f\u0645.  \u0622\u062e\u0631\u06cc\u0646 \u0627\u0645\u0627 \u0646\u0647 \u06a9\u0645\u200c\u0627\u0647\u0645\u06cc\u062a \u06a9\u0647 \u0645\u0646 \u0628\u0647 \u0622\u0646 \u067e\u0631\u062f\u0627\u062e\u062a\u0645 \u0631\u0648\u06cc \u0622 <code>to_dict()<\/code> \u0631\u0648\u0634\u06cc \u0628\u0631\u0627\u06cc \u06a9\u0645\u06a9 \u0628\u0647 \u0633\u0631\u06cc\u0627\u0644 \u0633\u0627\u0632\u06cc \u0627\u0634\u06cc\u0627\u0621 \u06a9\u0627\u0631\u0628\u0631.<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"\"\"\nmodels.py\n- Data classes for the surveyapi application\n\"\"\"<\/span>\n\n<span class=\"hljs-comment\">#<\/span>\n<span class=\"hljs-comment\"># omitting imports and what not<\/span>\n<span class=\"hljs-comment\">#<\/span>\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">User<\/span>(<span class=\"hljs-params\">db.Model<\/span>):<\/span>\n    __tablename__ = <span class=\"hljs-string\">'users'<\/span>\n\n    <span class=\"hljs-built_in\">id<\/span> = db.Column(db.Integer, primary_key=<span class=\"hljs-literal\">True<\/span>)\n    email = db.Column(db.String(<span class=\"hljs-number\">120<\/span>), unique=<span class=\"hljs-literal\">True<\/span>, nullable=<span class=\"hljs-literal\">False<\/span>)\n    password = db.Column(db.String(<span class=\"hljs-number\">255<\/span>), nullable=<span class=\"hljs-literal\">False<\/span>)\n    surveys = db.relationship(<span class=\"hljs-string\">'Survey'<\/span>, backref=<span class=\"hljs-string\">\"creator\"<\/span>, lazy=<span class=\"hljs-literal\">False<\/span>)\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">__init__<\/span>(<span class=\"hljs-params\">self, email, password<\/span>):<\/span>\n        self.email = email\n        self.password = generate_password_hash(password, method=<span class=\"hljs-string\">'sha256'<\/span>)\n\n<span class=\"hljs-meta\">    @classmethod<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">authenticate<\/span>(<span class=\"hljs-params\">cls, **kwargs<\/span>):<\/span>\n        email = kwargs.get(<span class=\"hljs-string\">'email'<\/span>)\n        password = kwargs.get(<span class=\"hljs-string\">'password'<\/span>)\n        \n        <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> email <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-keyword\">not<\/span> password:\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">None<\/span>\n\n        user = cls.query.filter_by(email=email).first()\n        <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> user <span class=\"hljs-keyword\">or<\/span> <span class=\"hljs-keyword\">not<\/span> check_password_hash(user.password, password):\n            <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">None<\/span>\n\n        <span class=\"hljs-keyword\">return<\/span> user\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">to_dict<\/span>(<span class=\"hljs-params\">self<\/span>):<\/span>\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">dict<\/span>(<span class=\"hljs-built_in\">id<\/span>=self.<span class=\"hljs-built_in\">id<\/span>, email=self.email)\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Survey<\/span>(<span class=\"hljs-params\">db.Model<\/span>):<\/span>\n    __tablename__ = <span class=\"hljs-string\">'surveys'<\/span>\n\n    <span class=\"hljs-built_in\">id<\/span> = db.Column(db.Integer, primary_key=<span class=\"hljs-literal\">True<\/span>)\n    name = db.Column(db.Text)\n    created_at = db.Column(db.DateTime, default=datetime.utcnow)\n    questions = db.relationship(<span class=\"hljs-string\">'Question'<\/span>, backref=<span class=\"hljs-string\">\"survey\"<\/span>, lazy=<span class=\"hljs-literal\">False<\/span>)\n    creator_id = db.Column(db.Integer, db.ForeignKey(<span class=\"hljs-string\">'users.id'<\/span>))\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">to_dict<\/span>(<span class=\"hljs-params\">self<\/span>):<\/span>\n      <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">dict<\/span>(<span class=\"hljs-built_in\">id<\/span>=self.<span class=\"hljs-built_in\">id<\/span>,\n                  name=self.name,\n                  created_at=self.created_at.strftime(<span class=\"hljs-string\">'%Y-%m-%d %H:%M:%S'<\/span>),\n                  questions=(question.to_dict() <span class=\"hljs-keyword\">for<\/span> question <span class=\"hljs-keyword\">in<\/span> self.questions))\n<\/code><\/pre>\n<p>\u0645\u0631\u062d\u0644\u0647 \u0628\u0639\u062f\u06cc \u0627\u06cc\u062c\u0627\u062f \u06cc\u06a9 \u0645\u0647\u0627\u062c\u0631\u062a \u062c\u062f\u06cc\u062f \u0648 \u0628\u0647 \u0631\u0648\u0632 \u0631\u0633\u0627\u0646\u06cc \u067e\u0627\u06cc\u06af\u0627\u0647 \u062f\u0627\u062f\u0647 \u0628\u0627 \u0622\u0646 \u0628\u0631\u0627\u06cc \u062c\u0641\u062a \u0634\u062f\u0646 \u0627\u0633\u062a <code>User<\/code> \u06a9\u0644\u0627\u0633 \u067e\u0627\u06cc\u062a\u0648\u0646 \u0628\u0627 \u062c\u062f\u0648\u0644 \u067e\u0627\u06cc\u06af\u0627\u0647 \u062f\u0627\u062f\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 SQLite.  \u0628\u0631\u0627\u06cc \u0627\u0646\u062c\u0627\u0645 \u0627\u06cc\u0646 \u06a9\u0627\u0631\u060c \u062f\u0633\u062a\u0648\u0631\u0627\u062a \u0632\u06cc\u0631 \u0631\u0627 \u062f\u0631 \u0647\u0645\u0627\u0646 \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0645\u0646 \u0627\u062c\u0631\u0627 \u0645\u06cc \u06a9\u0646\u0645 <code>manage.py<\/code> \u0645\u062f\u0648\u0644.<\/p>\n<pre><code class=\"hljs\">(venv) $ python manage.py db migrate\n(venv) $ python manage.py db upgrade\n<\/code><\/pre>\n<p>\u062e\u0648\u0628\u060c \u0648\u0642\u062a \u0622\u0646 \u0627\u0633\u062a \u06a9\u0647 \u0628\u0647 \u0622\u0646 \u0628\u0631\u0648\u06cc\u062f <code>api.py<\/code> \u0645\u0627\u0698\u0648\u0644 \u0648 \u0627\u062c\u0631\u0627\u06cc \u0639\u0645\u0644\u06a9\u0631\u062f \u062b\u0628\u062a \u0646\u0627\u0645 \u0648 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0628\u0647 \u0647\u0645\u0631\u0627\u0647 \u0639\u0645\u0644\u06a9\u0631\u062f \u062a\u0623\u06cc\u06cc\u062f \u0628\u0631\u0627\u06cc \u0645\u062d\u0627\u0641\u0638\u062a \u0627\u0632 \u0627\u06cc\u062c\u0627\u062f \u0646\u0638\u0631\u0633\u0646\u062c\u06cc \u0647\u0627\u06cc \u062c\u062f\u06cc\u062f.  \u0627\u0632 \u0627\u06cc\u0646 \u06af\u0630\u0634\u062a\u0647\u060c \u0645\u0646 \u0646\u0645\u06cc \u062e\u0648\u0627\u0647\u0645 \u0647\u06cc\u0686 \u0631\u0628\u0627\u062a \u0648\u0628 \u0634\u0631\u0648\u0631 \u06cc\u0627 \u0633\u0627\u06cc\u0631 \u0628\u0627\u0632\u06cc\u06af\u0631\u0627\u0646 \u0628\u062f\u06cc \u06a9\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0638\u0631\u0633\u0646\u062c\u06cc \u0639\u0627\u0644\u06cc \u0645\u0646 \u0631\u0627 \u0622\u0644\u0648\u062f\u0647 \u06a9\u0646\u0646\u062f.<\/p>\n<p>\u0628\u0631\u0627\u06cc \u0634\u0631\u0648\u0639 \u0645\u0646 \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc \u06a9\u0646\u0645 <code>User<\/code> \u06a9\u0644\u0627\u0633 \u0628\u0647 \u0644\u06cc\u0633\u062a \u0648\u0627\u0631\u062f\u0627\u062a \u0627\u0632 <code>models.py<\/code> \u0645\u0627\u0698\u0648\u0644 \u0628\u0647 \u0633\u0645\u062a \u0628\u0627\u0644\u0627\u06cc <code>api.py<\/code> \u0645\u062f\u0648\u0644.  \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u0645\u0646 \u062f\u0631 \u0622\u0646\u062c\u0627 \u0647\u0633\u062a\u0645\u060c \u0627\u062f\u0627\u0645\u0647 \u062e\u0648\u0627\u0647\u0645 \u062f\u0627\u062f \u0648 \u0686\u0646\u062f \u0648\u0627\u0631\u062f\u0627\u062a \u062f\u06cc\u06af\u0631 \u0631\u0627 \u06a9\u0647 \u0628\u0639\u062f\u0627\u064b \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062e\u0648\u0627\u0647\u0645 \u06a9\u0631\u062f\u060c \u0627\u0636\u0627\u0641\u0647 \u062e\u0648\u0627\u0647\u0645 \u06a9\u0631\u062f.<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"\"\"\napi.py\n- provides the API endpoints for consuming and producing \n  REST requests and responses\n\"\"\"<\/span>\n\n<span class=\"hljs-keyword\">from<\/span> functools <span class=\"hljs-keyword\">import<\/span> wraps\n<span class=\"hljs-keyword\">from<\/span> datetime <span class=\"hljs-keyword\">import<\/span> datetime, timedelta\n\n<span class=\"hljs-keyword\">from<\/span> flask <span class=\"hljs-keyword\">import<\/span> Blueprint, jsonify, request, current_app\n\n<span class=\"hljs-keyword\">import<\/span> jwt\n\n<span class=\"hljs-keyword\">from<\/span> .models <span class=\"hljs-keyword\">import<\/span> db, Survey, Question, Choice, User\n<\/code><\/pre>\n<p>\u0627\u06a9\u0646\u0648\u0646 \u06a9\u0647 \u062a\u0645\u0627\u0645 \u0627\u0628\u0632\u0627\u0631\u0647\u0627\u06cc \u0645\u0648\u0631\u062f \u0646\u06cc\u0627\u0632 \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0631\u062f\u0647 \u0627\u0645\u060c \u0645\u06cc \u062a\u0648\u0627\u0646\u0645 \u0645\u062c\u0645\u0648\u0639\u0647 \u0627\u06cc \u0627\u0632 \u062a\u0648\u0627\u0628\u0639 \u062b\u0628\u062a \u0646\u0627\u0645 \u0648 \u0646\u0645\u0627\u06cc \u0648\u0631\u0648\u062f \u0628\u0647 \u0633\u06cc\u0633\u062a\u0645 \u0631\u0627 \u062f\u0631 <code>api.py<\/code> \u0645\u062f\u0648\u0644.<\/p>\n<p>\u0645\u0646 \u0628\u0627 \u0627\u06cc\u0646 \u0634\u0631\u0648\u0639 \u062e\u0648\u0627\u0647\u0645 \u06a9\u0631\u062f <code>register()<\/code> \u0639\u0645\u0644\u06a9\u0631\u062f \u0631\u0627 \u0645\u0634\u0627\u0647\u062f\u0647 \u06a9\u0646\u06cc\u062f \u06a9\u0647 \u0627\u0646\u062a\u0638\u0627\u0631 \u062f\u0627\u0631\u062f \u0627\u06cc\u0645\u06cc\u0644 \u0648 \u0631\u0645\u0632 \u0639\u0628\u0648\u0631 \u0647\u0645\u0631\u0627\u0647 \u0628\u0627 JSON \u062f\u0631 \u0645\u062a\u0646 \u062f\u0631\u062e\u0648\u0627\u0633\u062a POST \u0627\u0631\u0633\u0627\u0644 \u0634\u0648\u062f.  \u06a9\u0627\u0631\u0628\u0631 \u0628\u0647 \u0633\u0627\u062f\u06af\u06cc \u0628\u0627 \u0647\u0631 \u0686\u06cc\u0632\u06cc \u06a9\u0647 \u0628\u0631\u0627\u06cc \u0627\u06cc\u0645\u06cc\u0644 \u0648 \u0631\u0645\u0632 \u0639\u0628\u0648\u0631 \u062f\u0627\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc\u200c\u0634\u0648\u062f \u0648 \u0645\u0646 \u0628\u0627 \u062e\u0648\u0634\u062d\u0627\u0644\u06cc \u067e\u0627\u0633\u062e JSON \u0631\u0627 \u0628\u0631\u0645\u06cc\u200c\u06af\u0631\u062f\u0627\u0646\u0645 (\u06a9\u0647 \u0644\u0632\u0648\u0645\u0627\u064b \u0628\u0647\u062a\u0631\u06cc\u0646 \u0631\u0648\u0634 \u0646\u06cc\u0633\u062a\u060c \u0627\u0645\u0627 \u0641\u0639\u0644\u0627\u064b \u06a9\u0627\u0631 \u062e\u0648\u0627\u0647\u062f \u06a9\u0631\u062f).<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"\"\"\napi.py\n- provides the API endpoints for consuming and producing \n  REST requests and responses\n\"\"\"<\/span>\n\n<span class=\"hljs-comment\">#<\/span>\n<span class=\"hljs-comment\"># omitting inputs and other view functions<\/span>\n<span class=\"hljs-comment\">#<\/span>\n\n<span class=\"hljs-meta\">@api.route(<span class=\"hljs-params\"><span class=\"hljs-string\">'\/register\/'<\/span>, methods=(<span class=\"hljs-params\"><span class=\"hljs-string\">'POST'<\/span>,<\/span>)<\/span>)<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">register<\/span>():<\/span>\n    data = request.get_json()\n    user = User(**data)\n    db.session.add(user)\n    db.session.commit()\n    <span class=\"hljs-keyword\">return<\/span> jsonify(user.to_dict()), <span class=\"hljs-number\">201<\/span>\n\n<\/code><\/pre>\n<p>\u0633\u0631\u062f.  \u067e\u0634\u062a\u06cc\u0628\u0627\u0646 \u0642\u0627\u062f\u0631 \u0627\u0633\u062a \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u062c\u062f\u06cc\u062f\u06cc \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u062f \u06a9\u0647 \u0645\u0634\u062a\u0627\u0642 \u0628\u0647 \u0627\u06cc\u062c\u0627\u062f \u06af\u0648\u062f\u0647\u0627\u06cc \u0646\u0638\u0631\u0633\u0646\u062c\u06cc \u0647\u0633\u062a\u0646\u062f\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646\u060c \u0628\u0647\u062a\u0631 \u0627\u0633\u062a \u0628\u0631\u062e\u06cc \u0627\u0632 \u0639\u0645\u0644\u06a9\u0631\u062f\u0647\u0627 \u0631\u0627 \u0628\u0631\u0627\u06cc \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0622\u0646\u0647\u0627 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u0645 \u0648 \u0628\u0647 \u0622\u0646\u0647\u0627 \u0627\u062c\u0627\u0632\u0647 \u0628\u062f\u0647\u0645 \u06a9\u0647 \u0622\u0646\u0647\u0627 \u0631\u0627 \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u0646\u062f. \u0631\u0648\u06cc \u0628\u0627 \u0627\u06cc\u062c\u0627\u062f \u0646\u0638\u0631\u0633\u0646\u062c\u06cc \u0647\u0627\u06cc \u062e\u0648\u062f<\/p>\n<p>\u062a\u0627\u0628\u0639 \u0648\u0631\u0648\u062f \u0628\u0647 \u0633\u06cc\u0633\u062a\u0645 \u0627\u0632 <code>User.authenticate(...)<\/code> \u0645\u062a\u062f \u06a9\u0644\u0627\u0633 \u0628\u0631\u0627\u06cc \u06cc\u0627\u0641\u062a\u0646 \u0648 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631.  \u0627\u06af\u0631 \u06a9\u0627\u0631\u0628\u0631 \u0645\u0637\u0627\u0628\u0642 \u0628\u0627 \u0627\u06cc\u0645\u06cc\u0644 \u0648 \u0631\u0645\u0632 \u0639\u0628\u0648\u0631 \u062f\u0627\u062f\u0647 \u0634\u062f\u0647 \u067e\u06cc\u062f\u0627 \u0634\u0648\u062f\u060c \u0639\u0645\u0644\u06a9\u0631\u062f \u0648\u0631\u0648\u062f \u0628\u0647 \u0633\u06cc\u0633\u062a\u0645 \u0628\u0631\u0627\u06cc \u0627\u06cc\u062c\u0627\u062f \u06cc\u06a9 \u0646\u0634\u0627\u0646\u0647 JWT \u067e\u06cc\u0634\u0631\u0641\u062a \u0645\u06cc \u06a9\u0646\u062f\u060c \u062f\u0631 \u063a\u06cc\u0631 \u0627\u06cc\u0646 \u0635\u0648\u0631\u062a <code>None<\/code> \u0628\u0631\u06af\u0631\u062f\u0627\u0646\u062f\u0647 \u0645\u06cc\u200c\u0634\u0648\u062f\u060c \u0648 \u062f\u0631 \u0646\u062a\u06cc\u062c\u0647 \u062a\u0627\u0628\u0639 \u0648\u0631\u0648\u062f \u0628\u0647 \u0633\u06cc\u0633\u062a\u0645\u060c \u067e\u06cc\u0627\u0645\u06cc \u0631\u0627 \u0628\u0627 \u06a9\u062f \u0648\u0636\u0639\u06cc\u062a HTTP 401 \u0628\u0631\u0645\u06cc\u200c\u06af\u0631\u062f\u0627\u0646\u062f.<\/p>\n<p>\u0645\u0646 \u062a\u0648\u06a9\u0646 JWT \u0631\u0627 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 PyJWT \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u0645 (\u0628\u0647 \u0639\u0646\u0648\u0627\u0646 <code>jwt<\/code>) \u0628\u0627 \u0631\u0645\u0632\u06af\u0630\u0627\u0631\u06cc \u06cc\u06a9 \u0641\u0631\u0647\u0646\u06af \u0644\u063a\u062a \u062d\u0627\u0648\u06cc \u0645\u0648\u0627\u0631\u062f \u0632\u06cc\u0631:<\/p>\n<ul>\n<li>\u0641\u0631\u0639\u06cc &#8211; \u0645\u0648\u0636\u0648\u0639 \u0627\u0632 <code>jwt<\/code>\u060c \u06a9\u0647 \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0648\u0631\u062f \u0627\u06cc\u0645\u06cc\u0644 \u06a9\u0627\u0631\u0628\u0631 \u0627\u0633\u062a<\/li>\n<li>iat &#8211; \u0632\u0645\u0627\u0646 <code>jwt<\/code> \u0635\u0627\u062f\u0631 \u0634\u062f \u062f\u0631<\/li>\n<li>exp &#8211; \u0644\u062d\u0638\u0647 \u0627\u06cc \u0627\u0633\u062a \u06a9\u0647 <code>jwt<\/code> \u0628\u0627\u06cc\u062f \u0645\u0646\u0642\u0636\u06cc \u0634\u0648\u062f \u06a9\u0647 \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0648\u0631\u062f 30 \u062f\u0642\u06cc\u0642\u0647 \u067e\u0633 \u0627\u0632 \u0635\u062f\u0648\u0631 \u0627\u0633\u062a<\/li>\n<\/ul>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"\"\"\napi.py\n- provides the API endpoints for consuming and producing \n  REST requests and responses\n\"\"\"<\/span>\n\n<span class=\"hljs-comment\">#<\/span>\n<span class=\"hljs-comment\"># omitting inputs and other view functions<\/span>\n<span class=\"hljs-comment\">#<\/span>\n\n<span class=\"hljs-meta\">@api.route(<span class=\"hljs-params\"><span class=\"hljs-string\">'\/login\/'<\/span>, methods=(<span class=\"hljs-params\"><span class=\"hljs-string\">'POST'<\/span>,<\/span>)<\/span>)<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">login<\/span>():<\/span>\n    data = request.get_json()\n    user = User.authenticate(**data)\n\n    <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> user:\n        <span class=\"hljs-keyword\">return<\/span> jsonify({ <span class=\"hljs-string\">'message'<\/span>: <span class=\"hljs-string\">'Invalid credentials'<\/span>, <span class=\"hljs-string\">'authenticated'<\/span>: <span class=\"hljs-literal\">False<\/span> }), <span class=\"hljs-number\">401<\/span>\n\n    token = jwt.encode({\n        <span class=\"hljs-string\">'sub'<\/span>: user.email,\n        <span class=\"hljs-string\">'iat'<\/span>:datetime.utcnow(),\n        <span class=\"hljs-string\">'exp'<\/span>: datetime.utcnow() + timedelta(minutes=<span class=\"hljs-number\">30<\/span>)},\n        current_app.config(<span class=\"hljs-string\">'SECRET_KEY'<\/span>))\n    <span class=\"hljs-keyword\">return<\/span> jsonify({ <span class=\"hljs-string\">'token'<\/span>: token.decode(<span class=\"hljs-string\">'UTF-8'<\/span>) })\n<\/code><\/pre>\n<p>\u0631\u0645\u0632\u06af\u0630\u0627\u0631\u06cc process \u0627\u0632 \u0627\u0631\u0632\u0634 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u062f <code>BaseConfig<\/code> \u06a9\u0644\u0627\u0633 <code>SECRET_KEY<\/code> \u062f\u0627\u0631\u0627\u06cc\u06cc \u062a\u0639\u0631\u06cc\u0641 \u0634\u062f\u0647 \u062f\u0631 <code>config.py<\/code> \u0648 \u062f\u0631 <code>current_app<\/code>\u0648\u06cc\u0698\u06af\u06cc \u067e\u06cc\u06a9\u0631\u0628\u0646\u062f\u06cc &#8216;s \u067e\u0633 \u0627\u0632 \u0627\u06cc\u062c\u0627\u062f \u0628\u0631\u0646\u0627\u0645\u0647 Flask.<\/p>\n<p>\u062f\u0631 \u0645\u0631\u062d\u0644\u0647 \u0628\u0639\u062f\u060c \u0645\u0646 \u0645\u06cc \u062e\u0648\u0627\u0647\u0645 \u0639\u0645\u0644\u06a9\u0631\u062f GET \u0648 POST \u0631\u0627 \u06a9\u0647 \u062f\u0631 \u062d\u0627\u0644 \u062d\u0627\u0636\u0631 \u062f\u0631 \u06cc\u06a9 \u062a\u0627\u0628\u0639 view \u0628\u0627 \u0646\u0627\u0645 \u0636\u0639\u06cc\u0641 \u0628\u0647 \u0646\u0627\u0645 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f\u060c \u062a\u062c\u0632\u06cc\u0647 \u06a9\u0646\u0645. <code>fetch_survey(...)<\/code> \u062f\u0631 \u0634\u06a9\u0644 \u0632\u06cc\u0631 \u0646\u0634\u0627\u0646 \u062f\u0627\u062f\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a.  \u062f\u0631 \u0639\u0648\u0636\u060c \u0627\u062c\u0627\u0632\u0647 \u062e\u0648\u0627\u0647\u0645 \u062f\u0627\u062f <code>fetch_surveys(...)<\/code> \u0647\u0646\u06af\u0627\u0645 \u062f\u0631\u062e\u0648\u0627\u0633\u062a &#8220;\/api\/surveys\/&#8221; \u0628\u0627 \u062f\u0631\u062e\u0648\u0627\u0633\u062a GET\u060c \u062a\u0646\u0647\u0627 \u0645\u0633\u0626\u0648\u0644 \u0648\u0627\u06a9\u0634\u06cc \u0647\u0645\u0647 \u0646\u0638\u0631\u0633\u0646\u062c\u06cc \u0647\u0627 \u0628\u0627\u0634\u06cc\u062f.  \u0627\u06cc\u062c\u0627\u062f \u0646\u0638\u0631\u0633\u0646\u062c\u06cc\u060c \u0631\u0648\u06cc \u0627\u0632 \u0633\u0648\u06cc \u062f\u06cc\u06af\u0631\u060c \u06a9\u0647 \u0632\u0645\u0627\u0646\u06cc \u0627\u062a\u0641\u0627\u0642 \u0645\u06cc \u0627\u0641\u062a\u062f \u06a9\u0647 \u0647\u0645\u0627\u0646 URL \u0628\u0627 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a POST \u0636\u0631\u0628\u0647 \u0645\u06cc \u062e\u0648\u0631\u062f\u060c \u0627\u06a9\u0646\u0648\u0646 \u062f\u0631 \u06cc\u06a9 \u062a\u0627\u0628\u0639 \u062c\u062f\u06cc\u062f \u0628\u0647 \u0646\u0627\u0645 \u0642\u0631\u0627\u0631 \u0645\u06cc \u06af\u06cc\u0631\u062f. <code>create_survey(...)<\/code>.<\/p>\n<p>\u067e\u0633 \u0627\u06cc\u0646 &#8230;<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"\"\"\napi.py\n- provides the API endpoints for consuming and producing \n  REST requests and responses\n\"\"\"<\/span>\n\n<span class=\"hljs-comment\">#<\/span>\n<span class=\"hljs-comment\"># omitting inputs and other view functions<\/span>\n<span class=\"hljs-comment\">#<\/span>\n\n<span class=\"hljs-meta\">@api.route(<span class=\"hljs-params\"><span class=\"hljs-string\">'\/surveys\/'<\/span>, methods=(<span class=\"hljs-params\"><span class=\"hljs-string\">'GET'<\/span>, <span class=\"hljs-string\">'POST'<\/span><\/span>)<\/span>)<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">fetch_surveys<\/span>():<\/span>\n    <span class=\"hljs-keyword\">if<\/span> request.method == <span class=\"hljs-string\">'GET'<\/span>:\n        surveys = Survey.query.<span class=\"hljs-built_in\">all<\/span>()\n        <span class=\"hljs-keyword\">return<\/span> jsonify((s.to_dict() <span class=\"hljs-keyword\">for<\/span> s <span class=\"hljs-keyword\">in<\/span> surveys))\n    <span class=\"hljs-keyword\">elif<\/span> request.method == <span class=\"hljs-string\">'POST'<\/span>:\n        data = request.get_json()\n        survey = Survey(name=data(<span class=\"hljs-string\">'name'<\/span>))\n        questions = ()\n        <span class=\"hljs-keyword\">for<\/span> q <span class=\"hljs-keyword\">in<\/span> data(<span class=\"hljs-string\">'questions'<\/span>):\n            question = Question(text=q(<span class=\"hljs-string\">'question'<\/span>))\n            question.choices = (Choice(text=c) <span class=\"hljs-keyword\">for<\/span> c <span class=\"hljs-keyword\">in<\/span> q(<span class=\"hljs-string\">'choices'<\/span>))\n            questions.append(question)\n        survey.questions = questions\n        db.session.add(survey)\n        db.session.commit()\n        <span class=\"hljs-keyword\">return<\/span> jsonify(survey.to_dict()), <span class=\"hljs-number\">201<\/span>\n<\/code><\/pre>\n<p>\u0645\u06cc \u0634\u0648\u062f \u0627\u06cc\u0646 &#8230;<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"\"\"\napi.py\n- provides the API endpoints for consuming and producing \n  REST requests and responses\n\"\"\"<\/span>\n\n<span class=\"hljs-comment\">#<\/span>\n<span class=\"hljs-comment\"># omitting inputs and other view functions<\/span>\n<span class=\"hljs-comment\">#<\/span>\n\n<span class=\"hljs-meta\">@api.route(<span class=\"hljs-params\"><span class=\"hljs-string\">'\/surveys\/'<\/span>, methods=(<span class=\"hljs-params\"><span class=\"hljs-string\">'POST'<\/span>,<\/span>)<\/span>)<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_survey<\/span>(<span class=\"hljs-params\">current_user<\/span>):<\/span>\n    data = request.get_json()\n    survey = Survey(name=data(<span class=\"hljs-string\">'name'<\/span>))\n    questions = ()\n    <span class=\"hljs-keyword\">for<\/span> q <span class=\"hljs-keyword\">in<\/span> data(<span class=\"hljs-string\">'questions'<\/span>):\n        question = Question(text=q(<span class=\"hljs-string\">'question'<\/span>))\n        question.choices = (Choice(text=c) <span class=\"hljs-keyword\">for<\/span> c <span class=\"hljs-keyword\">in<\/span> q(<span class=\"hljs-string\">'choices'<\/span>))\n        questions.append(question)\n    survey.questions = questions\n    survey.creator = current_user\n    db.session.add(survey)\n    db.session.commit()\n    <span class=\"hljs-keyword\">return<\/span> jsonify(survey.to_dict()), <span class=\"hljs-number\">201<\/span>\n\n\n<span class=\"hljs-meta\">@api.route(<span class=\"hljs-params\"><span class=\"hljs-string\">'\/surveys\/'<\/span>, methods=(<span class=\"hljs-params\"><span class=\"hljs-string\">'GET'<\/span>,<\/span>)<\/span>)<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">fetch_surveys<\/span>():<\/span>\n    surveys = Survey.query.<span class=\"hljs-built_in\">all<\/span>()\n    <span class=\"hljs-keyword\">return<\/span> jsonify((s.to_dict() <span class=\"hljs-keyword\">for<\/span> s <span class=\"hljs-keyword\">in<\/span> surveys))\n<\/code><\/pre>\n<p>\u06a9\u0644\u06cc\u062f \u0648\u0627\u0642\u0639\u06cc \u062f\u0631 \u062d\u0627\u0644 \u062d\u0627\u0636\u0631 \u0645\u062d\u0627\u0641\u0638\u062a \u0627\u0632 \u0622\u0646 \u0627\u0633\u062a <code>create_survey(...)<\/code> \u0639\u0645\u0644\u06a9\u0631\u062f \u0631\u0627 \u0645\u0634\u0627\u0647\u062f\u0647 \u06a9\u0646\u06cc\u062f \u062a\u0627 \u0641\u0642\u0637 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u062a\u0623\u06cc\u06cc\u062f \u0634\u062f\u0647 \u0628\u062a\u0648\u0627\u0646\u0646\u062f \u0646\u0638\u0631\u0633\u0646\u062c\u06cc \u062c\u062f\u06cc\u062f \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0646\u062f.  \u0628\u0647 \u0631\u0648\u0634\u06cc \u062f\u06cc\u06af\u0631\u060c \u0627\u06af\u0631 \u06cc\u06a9 \u062f\u0631\u062e\u0648\u0627\u0633\u062a POST \u0639\u0644\u06cc\u0647 &#8220;\/api\/surveys&#8221; \u0627\u0646\u062c\u0627\u0645 \u0634\u0648\u062f\u060c \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0627\u06cc\u062f \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u062f \u06a9\u0647 \u062a\u0648\u0633\u0637 \u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631 \u0645\u0639\u062a\u0628\u0631 \u0648 \u062a\u0623\u06cc\u06cc\u062f \u0634\u062f\u0647 \u0627\u0646\u062c\u0627\u0645 \u0634\u062f\u0647 \u0628\u0627\u0634\u062f.<\/p>\n<p>\u062f\u06a9\u0648\u0631\u0627\u062a\u0648\u0631 \u0645\u0641\u06cc\u062f \u067e\u0627\u06cc\u062a\u0648\u0646 \u0648\u0627\u0631\u062f \u0645\u06cc \u0634\u0648\u062f!  \u0645\u0646 \u0627\u0632 \u062f\u06a9\u0648\u0631\u0627\u062a\u0648\u0631 \u0628\u0631\u0627\u06cc \u0628\u0633\u062a\u0647 \u0628\u0646\u062f\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062e\u0648\u0627\u0647\u0645 \u06a9\u0631\u062f <code>create_survey(...)<\/code> \u0639\u0645\u0644\u06a9\u0631\u062f \u0631\u0627 \u0645\u0634\u0627\u0647\u062f\u0647 \u06a9\u0646\u06cc\u062f \u06a9\u0647 \u0628\u0631\u0631\u0633\u06cc \u0645\u06cc\u200c\u06a9\u0646\u062f \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u06a9\u0646\u0646\u062f\u0647 \u062f\u0627\u0631\u0627\u06cc \u06cc\u06a9 \u0646\u0634\u0627\u0646\u0647 JWT \u0645\u0639\u062a\u0628\u0631 \u062f\u0631 \u0633\u0631\u0628\u0631\u06af \u062e\u0648\u062f \u0627\u0633\u062a \u0648 \u062f\u0631\u062e\u0648\u0627\u0633\u062a\u200c\u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0641\u0627\u0642\u062f \u0622\u0646 \u0647\u0633\u062a\u0646\u062f \u0631\u0627 \u0631\u062f \u0645\u06cc\u200c\u06a9\u0646\u062f.  \u0645\u0646 \u0628\u0647 \u0627\u06cc\u0646 \u062f\u06a9\u0648\u0631\u0627\u062a\u0648\u0631 \u0632\u0646\u06af \u0645\u06cc \u0632\u0646\u0645 <code>token_required<\/code> \u0648 \u0622\u0646 \u0631\u0627 \u0628\u0627\u0644\u0627\u062a\u0631 \u0627\u0632 \u0647\u0645\u0647 \u062a\u0648\u0627\u0628\u0639 view \u062f\u06cc\u06af\u0631 \u062f\u0631 \u0622\u0646 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u06a9\u0646\u06cc\u062f <code>api.py<\/code> \u0645\u0627\u0646\u0646\u062f:<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"\"\"\napi.py\n- provides the API endpoints for consuming and producing \n  REST requests and responses\n\"\"\"<\/span>\n\n<span class=\"hljs-comment\">#<\/span>\n<span class=\"hljs-comment\"># omitting inputs and other view functions<\/span>\n<span class=\"hljs-comment\">#<\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">token_required<\/span>(<span class=\"hljs-params\">f<\/span>):<\/span>\n<span class=\"hljs-meta\">    @wraps(<span class=\"hljs-params\">f<\/span>)<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">_verify<\/span>(<span class=\"hljs-params\">*args, **kwargs<\/span>):<\/span>\n        auth_headers = request.headers.get(<span class=\"hljs-string\">'Authorization'<\/span>, <span class=\"hljs-string\">''<\/span>).split()\n\n        invalid_msg = {\n            <span class=\"hljs-string\">'message'<\/span>: <span class=\"hljs-string\">'Invalid token. Registeration and \/ or authentication required'<\/span>,\n            <span class=\"hljs-string\">'authenticated'<\/span>: <span class=\"hljs-literal\">False<\/span>\n        }\n        expired_msg = {\n            <span class=\"hljs-string\">'message'<\/span>: <span class=\"hljs-string\">'Expired token. Reauthentication required.'<\/span>,\n            <span class=\"hljs-string\">'authenticated'<\/span>: <span class=\"hljs-literal\">False<\/span>\n        }\n\n        <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-built_in\">len<\/span>(auth_headers) != <span class=\"hljs-number\">2<\/span>:\n            <span class=\"hljs-keyword\">return<\/span> jsonify(invalid_msg), <span class=\"hljs-number\">401<\/span>\n\n        <span class=\"hljs-keyword\">try<\/span>:\n            token = auth_headers(<span class=\"hljs-number\">1<\/span>)\n            data = jwt.decode(token, current_app.config(<span class=\"hljs-string\">'SECRET_KEY'<\/span>))\n            user = User.query.filter_by(email=data(<span class=\"hljs-string\">'sub'<\/span>)).first()\n            <span class=\"hljs-keyword\">if<\/span> <span class=\"hljs-keyword\">not<\/span> user:\n                <span class=\"hljs-keyword\">raise<\/span> RuntimeError(<span class=\"hljs-string\">'User not found'<\/span>)\n            <span class=\"hljs-keyword\">return<\/span> f(user, *args, **kwargs)\n        <span class=\"hljs-keyword\">except<\/span> jwt.ExpiredSignatureError:\n            <span class=\"hljs-keyword\">return<\/span> jsonify(expired_msg), <span class=\"hljs-number\">401<\/span> <span class=\"hljs-comment\"># 401 is Unauthorized HTTP status code<\/span>\n        <span class=\"hljs-keyword\">except<\/span> (jwt.InvalidTokenError, Exception) <span class=\"hljs-keyword\">as<\/span> e:\n            <span class=\"hljs-built_in\">print<\/span>(e)\n            <span class=\"hljs-keyword\">return<\/span> jsonify(invalid_msg), <span class=\"hljs-number\">401<\/span>\n\n    <span class=\"hljs-keyword\">return<\/span> _verify\n<\/code><\/pre>\n<p>\u0645\u0646\u0637\u0642 \u0627\u0635\u0644\u06cc \u0627\u06cc\u0646 \u062f\u06a9\u0648\u0631\u0627\u062a\u0648\u0631 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647:<\/p>\n<ol>\n<li>\u0627\u0637\u0645\u06cc\u0646\u0627\u0646 \u062d\u0627\u0635\u0644 \u06a9\u0646\u06cc\u062f \u06a9\u0647 \u062d\u0627\u0648\u06cc \u0633\u0631\u0635\u0641\u062d\u0647 &#8220;Authorization&#8221; \u0628\u0627 \u0631\u0634\u062a\u0647 \u0627\u06cc \u0627\u0633\u062a \u06a9\u0647 \u0634\u0628\u06cc\u0647 \u06cc\u06a9 \u062a\u0648\u06a9\u0646 JWT \u0627\u0633\u062a.<\/li>\n<li>\u062a\u0623\u06cc\u06cc\u062f \u06a9\u0646\u06cc\u062f \u06a9\u0647 JWT \u0645\u0646\u0642\u0636\u06cc \u0646\u0634\u062f\u0647 \u0627\u0633\u062a\u060c \u06a9\u0647 PyJWT \u0628\u0627 \u067e\u0631\u062a\u0627\u0628 \u06a9\u0631\u062f\u0646 \u0627\u0632 \u0645\u0646 \u0645\u0631\u0627\u0642\u0628\u062a \u0645\u06cc \u06a9\u0646\u062f <code>ExpiredSignatureError<\/code> \u0627\u06af\u0631 \u062f\u06cc\u06af\u0631 \u0645\u0639\u062a\u0628\u0631 \u0646\u06cc\u0633\u062a<\/li>\n<li>\u062a\u0623\u06cc\u06cc\u062f \u06a9\u0646\u06cc\u062f \u06a9\u0647 JWT \u06cc\u06a9 \u062a\u0648\u06a9\u0646 \u0645\u0639\u062a\u0628\u0631 \u0627\u0633\u062a\u060c \u06a9\u0647 PyJWT \u0646\u06cc\u0632 \u0628\u0627 \u067e\u0631\u062a\u0627\u0628 a \u0627\u0632 \u0622\u0646 \u0645\u0631\u0627\u0642\u0628\u062a \u0645\u06cc \u06a9\u0646\u062f <code>InvalidTokenError<\/code> \u0627\u06af\u0631 \u0645\u0639\u062a\u0628\u0631 \u0646\u06cc\u0633\u062a<\/li>\n<li>\u0627\u06af\u0631 \u0647\u0645\u0647 \u0645\u0639\u062a\u0628\u0631 \u0628\u0627\u0634\u0646\u062f\u060c \u06a9\u0627\u0631\u0628\u0631 \u0645\u0631\u062a\u0628\u0637 \u0627\u0632 \u067e\u0627\u06cc\u06af\u0627\u0647 \u062f\u0627\u062f\u0647 \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0645\u06cc \u0634\u0648\u062f \u0648 \u0628\u0647 \u0639\u0645\u0644\u06a9\u0631\u062f\u06cc \u06a9\u0647 \u062a\u0632\u0626\u06cc\u0646 \u06a9\u0646\u0646\u062f\u0647 \u062f\u0631 \u062d\u0627\u0644 \u0628\u0633\u062a\u0647 \u0628\u0646\u062f\u06cc \u0627\u0633\u062a \u0628\u0627\u0632\u06af\u0631\u062f\u0627\u0646\u062f\u0647 \u0645\u06cc \u0634\u0648\u062f.<\/li>\n<\/ol>\n<p>\u0627\u06a9\u0646\u0648\u0646 \u062a\u0646\u0647\u0627 \u0686\u06cc\u0632\u06cc \u06a9\u0647 \u0628\u0627\u0642\u06cc \u0645\u0627\u0646\u062f\u0647 \u0627\u0633\u062a \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u0646 \u062f\u06a9\u0648\u0631\u0627\u062a\u0648\u0631 \u0628\u0647 \u0622\u0646 \u0627\u0633\u062a <code>create_survey(...)<\/code> \u0631\u0648\u0634\u06cc \u0645\u062b\u0644 \u0627\u06cc\u0646:<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-string\">\"\"\"\napi.py\n- provides the API endpoints for consuming and producing \n  REST requests and responses\n\"\"\"<\/span>\n\n<span class=\"hljs-comment\">#<\/span>\n<span class=\"hljs-comment\"># omitting inputs and other functions<\/span>\n<span class=\"hljs-comment\">#<\/span>\n\n<span class=\"hljs-meta\">@api.route(<span class=\"hljs-params\"><span class=\"hljs-string\">'\/surveys\/'<\/span>, methods=(<span class=\"hljs-params\"><span class=\"hljs-string\">'POST'<\/span>,<\/span>)<\/span>)<\/span>\n<span class=\"hljs-meta\">@token_required<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">def<\/span> <span class=\"hljs-title\">create_survey<\/span>(<span class=\"hljs-params\">current_user<\/span>):<\/span>\n    data = request.get_json()\n    survey = Survey(name=data(<span class=\"hljs-string\">'name'<\/span>))\n    questions = ()\n    <span class=\"hljs-keyword\">for<\/span> q <span class=\"hljs-keyword\">in<\/span> data(<span class=\"hljs-string\">'questions'<\/span>):\n        question = Question(text=q(<span class=\"hljs-string\">'question'<\/span>))\n        question.choices = (Choice(text=c) <span class=\"hljs-keyword\">for<\/span> c <span class=\"hljs-keyword\">in<\/span> q(<span class=\"hljs-string\">'choices'<\/span>))\n        questions.append(question)\n    survey.questions = questions\n    survey.creator = current_user\n    db.session.add(survey)\n    db.session.commit()\n    <span class=\"hljs-keyword\">return<\/span> jsonify(survey.to_dict()), <span class=\"hljs-number\">201<\/span>\n<\/code><\/pre>\n<h2 id=\"implementingjwtauthenticationinvuejsspa\"><span class=\"ez-toc-section\" id=\"%d9%be%db%8c%d8%a7%d8%af%d9%87_%d8%b3%d8%a7%d8%b2%db%8c_jwt_authentication_%d8%af%d8%b1_vuejs_spa\"><\/span>\u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc JWT Authentication \u062f\u0631 Vue.js SPA<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0628\u0627 \u062a\u06a9\u0645\u06cc\u0644 \u0642\u0633\u0645\u062a \u067e\u0634\u062a\u06cc \u0645\u0639\u0627\u062f\u0644\u0647 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a\u060c \u0627\u06a9\u0646\u0648\u0646 \u0628\u0627\u06cc\u062f \u062f\u06a9\u0645\u0647 \u0633\u0645\u062a \u06a9\u0644\u0627\u06cc\u0646\u062a \u0631\u0627 \u0628\u0627 \u0627\u062c\u0631\u0627\u06cc \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a JWT \u062f\u0631 Vue.js \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u0645.  \u0645\u0646 \u0628\u0627 \u0627\u06cc\u062c\u0627\u062f \u06cc\u06a9 \u0645\u0627\u0698\u0648\u0644 \u062c\u062f\u06cc\u062f \u062f\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0628\u0647 \u0646\u0627\u0645 &#8220;utils&#8221; \u062f\u0631 \u062f\u0627\u062e\u0644 \u0628\u0631\u0646\u0627\u0645\u0647 \u0634\u0631\u0648\u0639 \u0645\u06cc \u06a9\u0646\u0645 <code>src<\/code> \u062f\u0627\u06cc\u0631\u06a9\u062a\u0648\u0631\u06cc \u0648 \u0642\u0631\u0627\u0631 \u062f\u0627\u062f\u0646 \u06cc\u06a9 <code>index.js<\/code> \u0641\u0627\u06cc\u0644 \u062f\u0627\u062e\u0644 \u067e\u0648\u0634\u0647 utils.  \u0627\u06cc\u0646 \u0645\u0627\u0698\u0648\u0644 \u0634\u0627\u0645\u0644 \u062f\u0648 \u0686\u06cc\u0632 \u062e\u0648\u0627\u0647\u062f \u0628\u0648\u062f:<\/p>\n<ol>\n<li>\u06af\u0630\u0631\u06af\u0627\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f\u06cc \u06a9\u0647 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0645 \u0627\u0632 \u0622\u0646 \u0628\u0631\u0627\u06cc \u0627\u0631\u0633\u0627\u0644 \u067e\u06cc\u0627\u0645\u200c\u0647\u0627 \u062f\u0631 \u0627\u0637\u0631\u0627\u0641 \u0628\u0631\u0646\u0627\u0645\u0647 \u0632\u0645\u0627\u0646\u06cc \u06a9\u0647 \u0645\u0648\u0627\u0631\u062f \u062e\u0627\u0635\u06cc \u0627\u062a\u0641\u0627\u0642 \u0645\u06cc\u200c\u0627\u0641\u062a\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0645\u060c \u0645\u0627\u0646\u0646\u062f \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0646\u0627\u0645\u0648\u0641\u0642 \u062f\u0631 \u0635\u0648\u0631\u062a \u0645\u0646\u0642\u0636\u06cc \u0634\u062f\u0646 JWT<\/li>\n<li>\u062a\u0627\u0628\u0639\u06cc \u0628\u0631\u0627\u06cc \u0628\u0631\u0631\u0633\u06cc \u06cc\u06a9 JWT \u062a\u0627 \u0628\u0628\u06cc\u0646\u062f \u0622\u06cc\u0627 \u0647\u0646\u0648\u0632 \u0645\u0639\u062a\u0628\u0631 \u0627\u0633\u062a \u06cc\u0627 \u062e\u06cc\u0631<\/li>\n<\/ol>\n<p>\u0627\u06cc\u0646 \u062f\u0648 \u0645\u0648\u0631\u062f \u0628\u0647 \u0627\u06cc\u0646 \u0635\u0648\u0631\u062a \u0627\u062c\u0631\u0627 \u0645\u06cc \u0634\u0648\u0646\u062f:<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-comment\">\/\/ utils\/index.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> Vue <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'vue'<\/span>\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> EventBus = <span class=\"hljs-keyword\">new<\/span> Vue()\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">isValidJwt<\/span> (<span class=\"hljs-params\">jwt<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">if<\/span> (!jwt || jwt.split(<span class=\"hljs-string\">'.'<\/span>).length &lt; <span class=\"hljs-number\">3<\/span>) {\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-literal\">false<\/span>\n  }\n  <span class=\"hljs-keyword\">const<\/span> data = <span class=\"hljs-built_in\">JSON<\/span>.parse(atob(jwt.split(<span class=\"hljs-string\">'.'<\/span>)(<span class=\"hljs-number\">1<\/span>)))\n  <span class=\"hljs-keyword\">const<\/span> exp = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>(data.exp * <span class=\"hljs-number\">1000<\/span>) <span class=\"hljs-comment\">\/\/ JS deals with dates in milliseconds since epoch<\/span>\n  <span class=\"hljs-keyword\">const<\/span> now = <span class=\"hljs-keyword\">new<\/span> <span class=\"hljs-built_in\">Date<\/span>()\n  <span class=\"hljs-keyword\">return<\/span> now &lt; exp\n}\n<\/code><\/pre>\n<p>\u0627\u06cc\u0646 <code>EventBus<\/code> \u0645\u062a\u063a\u06cc\u0631 \u0641\u0642\u0637 \u0646\u0645\u0648\u0646\u0647 \u0627\u06cc \u0627\u0632 \u0634\u06cc Vue \u0627\u0633\u062a.  \u0645\u0646 \u0645\u06cc \u062a\u0648\u0627\u0646\u0645 \u0627\u0632 \u0627\u06cc\u0646 \u0648\u0627\u0642\u0639\u06cc\u062a \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0645 \u06a9\u0647 \u0634\u06cc Vue \u0647\u0631 \u062f\u0648 \u06cc\u06a9 \u0631\u0627 \u062f\u0627\u0631\u062f <code>$emit<\/code> \u0648 \u06cc\u06a9 \u062c\u0641\u062a <code>$\u0631\u0648\u06cc<\/code> \/ <code>$off<\/code> \u0631\u0648\u0634 \u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0631\u0648\u06cc\u062f\u0627\u062f\u0647\u0627 \u0648 \u0647\u0645\u0686\u0646\u06cc\u0646 \u062b\u0628\u062a \u0648 \u0644\u063a\u0648 \u062b\u0628\u062a \u0631\u0648\u06cc\u062f\u0627\u062f\u0647\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u0634\u0648\u0646\u062f.<\/p>\n<p>\u0627\u06cc\u0646 <code>isValid(jwt)<\/code> \u062a\u0627\u0628\u0639 \u0686\u06cc\u0632\u06cc \u0627\u0633\u062a \u06a9\u0647 \u0645\u0646 \u0628\u0631\u0627\u06cc \u062a\u0639\u06cc\u06cc\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u0622\u06cc\u0627 \u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631 \u0645\u0628\u062a\u0646\u06cc \u0628\u0631 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0627\u0633\u062a \u06cc\u0627 \u062e\u06cc\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u062e\u0648\u0627\u0647\u0645 \u06a9\u0631\u062f \u0631\u0648\u06cc \u0627\u0637\u0644\u0627\u0639\u0627\u062a \u0645\u0648\u062c\u0648\u062f \u062f\u0631 JWT  \u0627\u0632 \u062a\u0648\u0636\u06cc\u062d \u0627\u0648\u0644\u06cc\u0647 \u0627\u0648\u0644\u06cc\u0647 JWT \u0647\u0627 \u0628\u0647 \u06cc\u0627\u062f \u0628\u06cc\u0627\u0648\u0631\u06cc\u062f \u06a9\u0647 \u0645\u062c\u0645\u0648\u0639\u0647 \u0627\u0633\u062a\u0627\u0646\u062f\u0627\u0631\u062f\u06cc \u0627\u0632 \u0648\u06cc\u0698\u06af\u06cc \u0647\u0627 \u062f\u0631 \u06cc\u06a9 \u0634\u06cc JSON \u06a9\u062f\u06af\u0630\u0627\u0631\u06cc \u0634\u062f\u0647 \u0628\u0647 \u0634\u06a9\u0644 &#8220;(HEADER).(PAYLOAD).(SIGNATURE)&#8221; \u0642\u0631\u0627\u0631 \u062f\u0627\u0631\u0646\u062f.  \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062b\u0627\u0644\u060c \u0628\u06af\u0648\u06cc\u06cc\u062f \u0645\u0646 JWT \u0632\u06cc\u0631 \u0631\u0627 \u062f\u0627\u0631\u0645:<\/p>\n<pre><code class=\"hljs\">eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJleGFtcGxlQG1haWwuY29tIiwiaWF0IjoxNTIyMzI2NzMyLCJleHAiOjE1MjIzMjg1MzJ9.1n9fx0vL9GumDGatwm2vfUqQl3yZ7Kl4t5NWMvW-pgw\n<\/code><\/pre>\n<p>\u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0645 \u0628\u062e\u0634 \u0645\u06cc\u0627\u0646\u06cc \u0628\u062f\u0646\u0647 \u0631\u0627 \u0631\u0645\u0632\u06af\u0634\u0627\u06cc\u06cc \u06a9\u0646\u0645 \u062a\u0627 \u0645\u062d\u062a\u0648\u0627\u06cc \u0622\u0646 \u0631\u0627 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u062c\u0627\u0648\u0627 \u0627\u0633\u06a9\u0631\u06cc\u067e\u062a \u0632\u06cc\u0631 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u0645:<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-keyword\">const<\/span> token = <span class=\"hljs-string\">'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJleGFtcGxlQG1haWwuY29tIiwiaWF0IjoxNTIyMzI2NzMyLCJleHAiOjE1MjIzMjg1MzJ9.1n9fx0vL9GumDGatwm2vfUqQl3yZ7Kl4t5NWMvW-pgw'<\/span>\n<span class=\"hljs-keyword\">const<\/span> tokenParts = token.split(<span class=\"hljs-string\">'.'<\/span>)\n<span class=\"hljs-keyword\">const<\/span> body = <span class=\"hljs-built_in\">JSON<\/span>.parse(atob(tokenParts(<span class=\"hljs-number\">1<\/span>)))\n<span class=\"hljs-built_in\">console<\/span>.log(body)   <span class=\"hljs-comment\">\/\/ {sub: \"(email\u00a0protected)\", iat: 1522326732, exp: 1522328532}<\/span>\n<\/code><\/pre>\n<p>\u062f\u0631 \u0627\u06cc\u0646\u062c\u0627 \u0645\u062d\u062a\u0648\u06cc\u0627\u062a \u0628\u062f\u0646\u0647 \u0646\u0634\u0627\u0646\u0647 \u0647\u0633\u062a\u0646\u062f <code>sub<\/code>\u060c \u0646\u0634\u0627\u0646 \u062f\u0647\u0646\u062f\u0647 \u0627\u06cc\u0645\u06cc\u0644 \u0645\u0634\u062a\u0631\u06a9\u060c <code>iat<\/code>\u060c \u06a9\u0647 \u062f\u0631 \u0645\u0647\u0631 \u0632\u0645\u0627\u0646\u06cc \u0628\u0631 \u062d\u0633\u0628 \u062b\u0627\u0646\u06cc\u0647 \u0635\u0627\u062f\u0631 \u0645\u06cc \u0634\u0648\u062f \u0648 <code>exp<\/code>\u060c \u06a9\u0647 \u0632\u0645\u0627\u0646\u06cc \u0627\u0633\u062a \u06a9\u0647 \u062f\u0631 \u0622\u0646 \u0646\u0634\u0627\u0646\u0647 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u062b\u0627\u0646\u06cc\u0647 \u0627\u0632 \u062f\u0648\u0631\u0647 \u0645\u0646\u0642\u0636\u06cc \u0645\u06cc \u0634\u0648\u062f (\u062a\u0639\u062f\u0627\u062f \u062b\u0627\u0646\u06cc\u0647 \u0647\u0627\u06cc\u06cc \u06a9\u0647 \u0627\u0632 1 \u0698\u0627\u0646\u0648\u06cc\u0647 1970 (\u0646\u06cc\u0645\u0647 \u0634\u0628 UTC\/GMT) \u0633\u067e\u0631\u06cc \u0634\u062f\u0647 \u0627\u0633\u062a\u060c \u0628\u062f\u0648\u0646 \u0627\u062d\u062a\u0633\u0627\u0628 \u062b\u0627\u0646\u06cc\u0647 \u0647\u0627\u06cc \u06a9\u0628\u06cc\u0633\u0647 (\u062f\u0631 ISO 8601: 1970-01-01T00: 00:00 Z)).  \u0647\u0645\u0627\u0646\u0637\u0648\u0631 \u06a9\u0647 \u0645\u06cc \u0628\u06cc\u0646\u06cc\u062f \u0645\u0646 \u0627\u0632 \u0622\u0646 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u0645 <code>exp<\/code> \u0627\u0631\u0632\u0634 \u062f\u0631 <code>isValidJwt(jwt)<\/code> \u0628\u0631\u0627\u06cc \u062a\u0639\u06cc\u06cc\u0646 \u0627\u06cc\u0646\u06a9\u0647 \u0622\u06cc\u0627 JWT \u0645\u0646\u0642\u0636\u06cc \u0634\u062f\u0647 \u0627\u0633\u062a \u06cc\u0627 \u062e\u06cc\u0631.<\/p>\n<p>\u0645\u0631\u062d\u0644\u0647 \u0628\u0639\u062f\u06cc \u0627\u0636\u0627\u0641\u0647 \u06a9\u0631\u062f\u0646 \u0686\u0646\u062f \u062a\u0648\u0627\u0628\u0639 \u062c\u062f\u06cc\u062f AJAX \u0628\u0631\u0627\u06cc \u0628\u0631\u0642\u0631\u0627\u0631\u06cc \u062a\u0645\u0627\u0633 \u0628\u0627 Flask REST API \u0628\u0631\u0627\u06cc \u062b\u0628\u062a \u0646\u0627\u0645 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u062c\u062f\u06cc\u062f \u0648 \u0644\u0627\u06af\u06cc\u0646 \u06a9\u0631\u062f\u0646 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u0645\u0648\u062c\u0648\u062f \u0627\u0633\u062a\u060c \u0628\u0647 \u0639\u0644\u0627\u0648\u0647 \u0645\u0646 \u0628\u0627\u06cc\u062f \u0622\u0646 \u0631\u0627 \u062a\u063a\u06cc\u06cc\u0631 \u062f\u0647\u0645. <code>postNewSurvey(...)<\/code> \u062a\u0627\u0628\u0639 \u0634\u0627\u0645\u0644 \u06cc\u06a9 \u0647\u062f\u0631 \u062d\u0627\u0648\u06cc JWT \u0627\u0633\u062a.<\/p>\n<pre><code class=\"hljs\">\n<span class=\"hljs-comment\">\/\/ api\/index.js<\/span>\n\n<span class=\"hljs-comment\">\/\/<\/span>\n<span class=\"hljs-comment\">\/\/ omitting stuff ... skipping to the bottom of the file<\/span>\n<span class=\"hljs-comment\">\/\/<\/span>\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">postNewSurvey<\/span> (<span class=\"hljs-params\">survey, jwt<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> axios.post(<span class=\"hljs-string\">`<span class=\"hljs-subst\">${API_URL}<\/span>\/surveys\/`<\/span>, survey, { <span class=\"hljs-attr\">headers<\/span>: { <span class=\"hljs-attr\">Authorization<\/span>: <span class=\"hljs-string\">`Bearer: <span class=\"hljs-subst\">${jwt}<\/span>`<\/span> } })\n}\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">authenticate<\/span> (<span class=\"hljs-params\">userData<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> axios.post(<span class=\"hljs-string\">`<span class=\"hljs-subst\">${API_URL}<\/span>\/login\/`<\/span>, userData)\n}\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">register<\/span> (<span class=\"hljs-params\">userData<\/span>) <\/span>{\n  <span class=\"hljs-keyword\">return<\/span> axios.post(<span class=\"hljs-string\">`<span class=\"hljs-subst\">${API_URL}<\/span>\/register\/`<\/span>, userData)\n}\n<\/code><\/pre>\n<p>\u062e\u0648\u0628\u060c \u0627\u06a9\u0646\u0648\u0646 \u0645\u06cc \u062a\u0648\u0627\u0646\u0645 \u0627\u0632 \u0627\u06cc\u0646 \u0645\u0648\u0627\u0631\u062f \u062f\u0631 \u0641\u0631\u0648\u0634\u06af\u0627\u0647 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u0645 \u062a\u0627 \u0648\u0636\u0639\u06cc\u062a \u0645\u0648\u0631\u062f \u0646\u06cc\u0627\u0632 \u0628\u0631\u0627\u06cc \u0627\u0631\u0627\u0626\u0647 \u0639\u0645\u0644\u06a9\u0631\u062f \u0635\u062d\u06cc\u062d \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0631\u0627 \u0645\u062f\u06cc\u0631\u06cc\u062a \u06a9\u0646\u0645.  \u0628\u0631\u0627\u06cc \u0634\u0631\u0648\u0639 \u0645\u0646 import <code>EventBus<\/code>  \u0648 <code>isValidJwt(...)<\/code> \u0639\u0645\u0644\u06a9\u0631\u062f \u0627\u0632 \u0645\u0627\u0698\u0648\u0644 utils \u0648 \u0647\u0645\u0686\u0646\u06cc\u0646 \u062f\u0648 \u0639\u0645\u0644\u06a9\u0631\u062f \u062c\u062f\u06cc\u062f AJAX \u0627\u0632 \u0645\u0627\u0698\u0648\u0644 api.  \u0633\u067e\u0633 \u06cc\u06a9 \u062a\u0639\u0631\u06cc\u0641 \u0627\u0632 a \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f <code>user<\/code> \u0634\u06cc\u0621 \u0648 \u0627\u0644\u0641 <code>jwt<\/code> \u0631\u0634\u062a\u0647 \u062a\u0648\u06a9\u0646 \u062f\u0631 \u0634\u06cc\u0621 \u062d\u0627\u0644\u062a \u0641\u0631\u0648\u0634\u06af\u0627\u0647 \u0645\u0627\u0646\u0646\u062f \u0627\u06cc\u0646 \u0627\u0633\u062a:<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-comment\">\/\/ store\/index.js<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> Vue <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'vue'<\/span>\n<span class=\"hljs-keyword\">import<\/span> Vuex <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'vuex'<\/span>\n\n<span class=\"hljs-comment\">\/\/ imports of AJAX functions will go here<\/span>\n<span class=\"hljs-keyword\">import<\/span> { fetchSurveys, fetchSurvey, saveSurveyResponse, postNewSurvey, authenticate, register } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@\/api'<\/span>\n<span class=\"hljs-keyword\">import<\/span> { isValidJwt, EventBus } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@\/utils'<\/span>\n\nVue.use(Vuex)\n\n<span class=\"hljs-keyword\">const<\/span> state = {\n  <span class=\"hljs-comment\">\/\/ single source of data<\/span>\n  <span class=\"hljs-attr\">surveys<\/span>: (),\n  <span class=\"hljs-attr\">currentSurvey<\/span>: {},\n  <span class=\"hljs-attr\">user<\/span>: {},\n  <span class=\"hljs-attr\">jwt<\/span>: <span class=\"hljs-string\">''<\/span>\n}\n\n<span class=\"hljs-comment\">\/\/<\/span>\n<span class=\"hljs-comment\">\/\/ omitting all the other stuff below<\/span>\n<span class=\"hljs-comment\">\/\/<\/span>\n<\/code><\/pre>\n<p>\u062f\u0631 \u0645\u0631\u062d\u0644\u0647 \u0628\u0639\u062f\u060c \u0645\u0646 \u0628\u0627\u06cc\u062f \u0686\u0646\u062f \u0631\u0648\u0634 \u0639\u0645\u0644 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u0645 \u06a9\u0647 \u06cc\u06a9\u06cc \u0627\u0632 \u0622\u0646\u0647\u0627 \u0631\u0627 \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u0645\u06cc \u06a9\u0646\u062f <code>register(...)<\/code> \u06cc\u0627 <code>authenticate(...)<\/code> \u062a\u0648\u0627\u0628\u0639 AJAX \u06a9\u0647 \u0645\u0627 \u0628\u0647 \u062a\u0627\u0632\u06af\u06cc \u062a\u0639\u0631\u06cc\u0641 \u06a9\u0631\u062f\u06cc\u0645.  \u0645\u0646 \u06a9\u0633\u06cc \u0631\u0627 \u06a9\u0647 \u0645\u0633\u0626\u0648\u0644 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631 \u0627\u0633\u062a \u0646\u0627\u0645 \u0645\u06cc \u0628\u0631\u0645 <code>login(...)<\/code>\u060c \u06a9\u0647 \u0628\u0647 \u0646\u0627\u0645 <code>authenticate(...)<\/code> \u062a\u0627\u0628\u0639 AJAX \u0648 \u0647\u0646\u06af\u0627\u0645\u06cc \u06a9\u0647 \u06cc\u06a9 \u067e\u0627\u0633\u062e \u0645\u0648\u0641\u0642\u06cc\u062a \u0622\u0645\u06cc\u0632 \u062d\u0627\u0648\u06cc \u06cc\u06a9 JWT \u062c\u062f\u06cc\u062f \u0631\u0627 \u0628\u0631\u0645\u06cc \u06af\u0631\u062f\u0627\u0646\u062f\u060c \u062c\u0647\u0634\u06cc \u0631\u0627 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc \u062f\u0647\u062f \u06a9\u0647 \u0645\u0646 \u0646\u0627\u0645 \u0645\u06cc \u0628\u0631\u0645. <code>setJwtToken<\/code>\u060c \u06a9\u0647 \u0628\u0627\u06cc\u062f \u0628\u0647 \u0634\u06cc mutations \u0627\u0636\u0627\u0641\u0647 \u0634\u0648\u062f.  \u062f\u0631 \u0635\u0648\u0631\u062a \u062f\u0631\u062e\u0648\u0627\u0633\u062a \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0646\u0627\u0645\u0648\u0641\u0642\u060c a \u0631\u0627 \u0632\u0646\u062c\u06cc\u0631\u0647 \u0645\u06cc \u06a9\u0646\u0645 <code>catch<\/code> \u0631\u0648\u0634 \u0628\u0647 \u0632\u0646\u062c\u06cc\u0631\u0647 \u0648\u0639\u062f\u0647 \u0628\u0631\u0627\u06cc \u06af\u0631\u0641\u062a\u0646 \u062e\u0637\u0627 \u0648 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 <code>EventBus<\/code> \u0628\u0631\u0627\u06cc \u0627\u0646\u062a\u0634\u0627\u0631 \u0631\u0648\u06cc\u062f\u0627\u062f\u06cc \u06a9\u0647 \u0628\u0647 \u0645\u0634\u062a\u0631\u06a9\u06cc\u0646 \u0627\u0637\u0644\u0627\u0639 \u0645\u06cc \u062f\u0647\u062f \u06a9\u0647 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0646\u0627\u0645\u0648\u0641\u0642 \u0627\u0633\u062a.<\/p>\n<p>\u0627\u06cc\u0646 <code>register(...)<\/code> \u0631\u0648\u0634 \u0639\u0645\u0644 \u06a9\u0627\u0645\u0644\u0627 \u0645\u0634\u0627\u0628\u0647 \u0627\u0633\u062a <code>login(...)<\/code>\u060c \u062f\u0631 \u0648\u0627\u0642\u0639\u060c \u062f\u0631 \u0648\u0627\u0642\u0639 \u0627\u0632 \u0622\u0646 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u06cc \u06a9\u0646\u062f <code>login(...)<\/code>.  \u0645\u0646 \u0647\u0645\u0686\u0646\u06cc\u0646 \u06cc\u06a9 \u0627\u0635\u0644\u0627\u062d \u06a9\u0648\u0686\u06a9 \u062f\u0631 \u0622\u0646 \u0646\u0634\u0627\u0646 \u0645\u06cc \u062f\u0647\u0645 <code>submitNewSurvey(...)<\/code> \u0645\u062a\u062f \u0639\u0645\u0644 \u06a9\u0647 \u062a\u0648\u06a9\u0646 JWT \u0631\u0627 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u06cc\u06a9 \u067e\u0627\u0631\u0627\u0645\u062a\u0631 \u0627\u0636\u0627\u0641\u06cc \u0628\u0647 <code>postNewSurvey(...)<\/code> \u062a\u0645\u0627\u0633 AJAX<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-keyword\">const<\/span> actions = {\n  <span class=\"hljs-comment\">\/\/ asynchronous operations<\/span>\n\n  <span class=\"hljs-comment\">\/\/<\/span>\n  <span class=\"hljs-comment\">\/\/ omitting the other action methods...<\/span>\n  <span class=\"hljs-comment\">\/\/<\/span>\n\n  login (context, userData) {\n    context.commit(<span class=\"hljs-string\">'setUserData'<\/span>, { userData })\n    <span class=\"hljs-keyword\">return<\/span> authenticate(userData)\n      .then(<span class=\"hljs-function\"><span class=\"hljs-params\">response<\/span> =&gt;<\/span> context.commit(<span class=\"hljs-string\">'setJwtToken'<\/span>, { <span class=\"hljs-attr\">jwt<\/span>: response.data }))\n      .catch(<span class=\"hljs-function\"><span class=\"hljs-params\">error<\/span> =&gt;<\/span> {\n        <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Error Authenticating: '<\/span>, error)\n        EventBus.$emit(<span class=\"hljs-string\">'failedAuthentication'<\/span>, error)\n      })\n  },\n  register (context, userData) {\n    context.commit(<span class=\"hljs-string\">'setUserData'<\/span>, { userData })\n    <span class=\"hljs-keyword\">return<\/span> register(userData)\n      .then(context.dispatch(<span class=\"hljs-string\">'login'<\/span>, userData))\n      .catch(<span class=\"hljs-function\"><span class=\"hljs-params\">error<\/span> =&gt;<\/span> {\n        <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Error Registering: '<\/span>, error)\n        EventBus.$emit(<span class=\"hljs-string\">'failedRegistering: '<\/span>, error)\n      })\n  },\n  submitNewSurvey (context, survey) {\n    <span class=\"hljs-keyword\">return<\/span> postNewSurvey(survey, context.state.jwt.token)\n  }\n}\n<\/code><\/pre>\n<p>\u0647\u0645\u0627\u0646\u0637\u0648\u0631 \u06a9\u0647 \u0642\u0628\u0644\u0627 \u0630\u06a9\u0631 \u0634\u062f\u060c \u0628\u0627\u06cc\u062f \u06cc\u06a9 \u062c\u0647\u0634 \u062c\u062f\u06cc\u062f \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u0645 \u06a9\u0647 \u0628\u0647 \u0635\u0631\u0627\u062d\u062a JWT \u0648 \u062f\u0627\u062f\u0647 \u0647\u0627\u06cc \u06a9\u0627\u0631\u0628\u0631 \u0631\u0627 \u062a\u0646\u0638\u06cc\u0645 \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-keyword\">const<\/span> mutations = {\n  <span class=\"hljs-comment\">\/\/ isolated data mutations<\/span>\n\n  <span class=\"hljs-comment\">\/\/<\/span>\n  <span class=\"hljs-comment\">\/\/ omitting the other mutation methods...<\/span>\n  <span class=\"hljs-comment\">\/\/<\/span>\n\n  setUserData (state, payload) {\n    <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'setUserData payload = '<\/span>, payload)\n    state.userData = payload.userData\n  },\n  setJwtToken (state, payload) {\n    <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'setJwtToken payload = '<\/span>, payload)\n    <span class=\"hljs-built_in\">localStorage<\/span>.token = payload.jwt.token\n    state.jwt = payload.jwt\n  }\n}\n<\/code><\/pre>\n<p>\u0622\u062e\u0631\u06cc\u0646 \u06a9\u0627\u0631\u06cc \u06a9\u0647 \u0645\u06cc \u062e\u0648\u0627\u0647\u0645 \u062f\u0631 \u0641\u0631\u0648\u0634\u06af\u0627\u0647 \u0627\u0646\u062c\u0627\u0645 \u062f\u0647\u0645 \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u06cc\u06a9 \u0645\u062a\u062f \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u0646\u062f\u0647 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u0645 \u06a9\u0647 \u062f\u0631 \u0686\u0646\u062f \u0645\u06a9\u0627\u0646 \u062f\u06cc\u06af\u0631 \u062f\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u0645\u06cc \u0634\u0648\u062f \u06a9\u0647 \u0646\u0634\u0627\u0646 \u0645\u06cc \u062f\u0647\u062f \u06a9\u0627\u0631\u0628\u0631 \u0641\u0639\u0644\u06cc \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0634\u062f\u0647 \u0627\u0633\u062a \u06cc\u0627 \u062e\u06cc\u0631.  \u0645\u0646 \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0631\u0627 \u0628\u0627 \u062a\u0645\u0627\u0633 \u06af\u0631\u0641\u062a\u0646 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc \u062f\u0647\u0645 <code>isValidJwt(jwt)<\/code> \u0639\u0645\u0644\u06a9\u0631\u062f \u0627\u0632 \u0645\u0627\u0698\u0648\u0644 utils \u062f\u0631 \u06af\u06cc\u0631\u0646\u062f\u0647 \u0628\u0647 \u0634\u0631\u062d \u0632\u06cc\u0631 \u0627\u0633\u062a:<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-keyword\">const<\/span> getters = {\n  <span class=\"hljs-comment\">\/\/ reusable data accessors<\/span>\n  isAuthenticated (state) {\n    <span class=\"hljs-keyword\">return<\/span> isValidJwt(state.jwt.token)\n  }\n}\n<\/code><\/pre>\n<p>\u0628\u0627\u0634\u0647 \u0646\u0632\u062f\u06cc\u06a9 \u0645\u06cc\u0634\u0645  \u0645\u0646 \u0628\u0627\u06cc\u062f \u06cc\u06a9 \u062c\u0632\u0621 Vue.js \u062c\u062f\u06cc\u062f \u0628\u0631\u0627\u06cc \u0648\u0631\u0648\u062f \/ \u062b\u0628\u062a \u0646\u0627\u0645 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u0645 page \u062f\u0631 \u0628\u0631\u0646\u0627\u0645\u0647.  \u0645\u0646 \u06cc\u06a9 \u0641\u0627\u06cc\u0644 \u0628\u0647 \u0646\u0627\u0645 \u0627\u06cc\u062c\u0627\u062f \u0645\u06cc \u06a9\u0646\u0645 <code>Login.vue<\/code> \u062f\u0631 \u0641\u0647\u0631\u0633\u062a \u0627\u062c\u0632\u0627\u06cc \u0633\u0627\u0632\u0646\u062f\u0647  \u062f\u0631 \u0628\u062e\u0634 \u0642\u0627\u0644\u0628 \u062f\u0648 \u0641\u06cc\u0644\u062f \u0648\u0631\u0648\u062f\u06cc \u0628\u0647 \u0622\u0646 \u0645\u06cc\u200c\u062f\u0647\u0645\u060c \u06cc\u06a9\u06cc \u0628\u0631\u0627\u06cc \u0627\u06cc\u0645\u06cc\u0644\u060c \u06a9\u0647 \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0646\u0627\u0645 \u06a9\u0627\u0631\u0628\u0631\u06cc \u0648 \u062f\u06cc\u06af\u0631\u06cc \u0628\u0631\u0627\u06cc \u0631\u0645\u0632 \u0639\u0628\u0648\u0631 \u0627\u0633\u062a.  \u062f\u0631 \u0632\u06cc\u0631 \u0622\u0646\u0647\u0627 \u062f\u0648 \u062f\u06a9\u0645\u0647 \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f\u060c \u06cc\u06a9\u06cc \u0628\u0631\u0627\u06cc \u0648\u0631\u0648\u062f \u0628\u0647 \u0633\u06cc\u0633\u062a\u0645 \u0627\u06af\u0631 \u0642\u0628\u0644\u0627\u064b \u06a9\u0627\u0631\u0628\u0631 \u062b\u0628\u062a \u0646\u0627\u0645 \u06a9\u0631\u062f\u0647 \u0627\u06cc\u062f \u0648 \u062f\u06cc\u06af\u0631\u06cc \u0628\u0631\u0627\u06cc \u062b\u0628\u062a \u0646\u0627\u0645.<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-comment\">&lt;!-- components\/Login.vue --&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">template<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">section<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"hero is-primary\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"hero-body\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container has-text-centered\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">h2<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"title\"<\/span>&gt;<\/span>Login or Register<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">h2<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">p<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"subtitle error-msg\"<\/span>&gt;<\/span>{{ errorMsg }}<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">p<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">section<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">section<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"section\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"field\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"label is-large\"<\/span> <span class=\"hljs-attr\">for<\/span>=<span class=\"hljs-string\">\"email\"<\/span>&gt;<\/span>Email:<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"control\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"email\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"input is-large\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"email\"<\/span> <span class=\"hljs-attr\">v-model<\/span>=<span class=\"hljs-string\">\"email\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"field\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">label<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"label is-large\"<\/span> <span class=\"hljs-attr\">for<\/span>=<span class=\"hljs-string\">\"password\"<\/span>&gt;<\/span>Password:<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">label<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"control\"<\/span>&gt;<\/span>\n            <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">input<\/span> <span class=\"hljs-attr\">type<\/span>=<span class=\"hljs-string\">\"password\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"input is-large\"<\/span> <span class=\"hljs-attr\">id<\/span>=<span class=\"hljs-string\">\"password\"<\/span> <span class=\"hljs-attr\">v-model<\/span>=<span class=\"hljs-string\">\"password\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"control\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"button is-large is-primary\"<\/span> @<span class=\"hljs-attr\">click<\/span>=<span class=\"hljs-string\">\"authenticate\"<\/span>&gt;<\/span>Login<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">a<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"button is-large is-success\"<\/span> @<span class=\"hljs-attr\">click<\/span>=<span class=\"hljs-string\">\"register\"<\/span>&gt;<\/span>Register<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">a<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">section<\/span>&gt;<\/span>\n\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">template<\/span>&gt;<\/span>\n<\/code><\/pre>\n<p>\u0628\u062f\u06cc\u0647\u06cc \u0627\u0633\u062a \u06a9\u0647 \u0627\u06cc\u0646 \u06a9\u0627\u0645\u067e\u0648\u0646\u0646\u062a \u0628\u0647 \u0628\u0631\u062e\u06cc \u0627\u0632 \u0648\u0636\u0639\u06cc\u062a \u0647\u0627\u06cc \u0645\u062d\u0644\u06cc \u0645\u0631\u062a\u0628\u0637 \u0628\u0627 \u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631 \u0646\u06cc\u0627\u0632 \u062f\u0627\u0631\u062f \u06a9\u0647 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0645\u0646 \u0627\u0632 \u0622\u0646 \u0646\u0634\u0627\u0646 \u062f\u0627\u062f\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a <code>v-model<\/code> \u062f\u0631 \u0641\u06cc\u0644\u062f\u0647\u0627\u06cc \u0648\u0631\u0648\u062f\u06cc\u060c \u0628\u0646\u0627\u0628\u0631\u0627\u06cc\u0646 \u0645\u0646 \u0622\u0646 \u0631\u0627 \u062f\u0631 \u0648\u06cc\u0698\u06af\u06cc \u062f\u0627\u062f\u0647 \u06a9\u0627\u0645\u067e\u0648\u0646\u0646\u062a \u0628\u0639\u062f\u06cc \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc \u06a9\u0646\u0645.  \u0645\u0646 \u0647\u0645\u0686\u0646\u06cc\u0646 \u0627\u0636\u0627\u0641\u0647 \u0645\u06cc \u06a9\u0646\u0645 <code>errorMsg<\/code> \u0648\u06cc\u0698\u06af\u06cc \u062f\u0627\u062f\u0647 \u06a9\u0647 \u0647\u0631 \u067e\u06cc\u0627\u0645\u06cc \u0631\u0627 \u06a9\u0647 \u062a\u0648\u0633\u0637 <code>EventBus<\/code> \u062f\u0631 \u0635\u0648\u0631\u062a \u0639\u062f\u0645 \u0645\u0648\u0641\u0642\u06cc\u062a \u062b\u0628\u062a \u0646\u0627\u0645 \u06cc\u0627 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a.  \u0628\u0631\u0627\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 <code>EventBus<\/code> \u0645\u0646 \u0645\u0634\u062a\u0631\u06a9 \u0647\u0633\u062a\u0645 <code>failedRegistering<\/code> \u0648 <code>failedAuthentication<\/code> \u062d\u0648\u0627\u062f\u062b \u062f\u0631 <code>mounted<\/code> \u0645\u0631\u062d\u0644\u0647 \u0686\u0631\u062e\u0647 \u062d\u06cc\u0627\u062a \u06a9\u0627\u0645\u067e\u0648\u0646\u0646\u062a Vue.js\u060c \u0648 \u0622\u0646\u0647\u0627 \u0631\u0627 \u062f\u0631 \u0622\u0646 \u0644\u063a\u0648 \u062b\u0628\u062a \u06a9\u0646\u06cc\u062f <code>beforeDestroy<\/code> \u0635\u062d\u0646\u0647.  \u0646\u06a9\u062a\u0647 \u062f\u06cc\u06af\u0631\u06cc \u06a9\u0647 \u0628\u0627\u06cc\u062f \u0628\u0647 \u0622\u0646 \u062a\u0648\u062c\u0647 \u06a9\u0631\u062f\u060c \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 \u0622\u0646 \u0627\u0633\u062a <code>@click<\/code> \u06a9\u0646\u062a\u0631\u0644\u200c\u06a9\u0646\u0646\u062f\u0647\u200c\u0647\u0627\u06cc \u0631\u0648\u06cc\u062f\u0627\u062f \u0628\u0627 \u06a9\u0644\u06cc\u06a9 \u06a9\u0631\u062f\u0646 \u0631\u0648\u06cc \u062f\u06a9\u0645\u0647\u200c\u0647\u0627\u06cc \u0648\u0631\u0648\u062f \u0648 \u062b\u0628\u062a \u0646\u0627\u0645 \u0641\u0631\u0627\u062e\u0648\u0627\u0646\u06cc \u0645\u06cc\u200c\u0634\u0648\u0646\u062f.  \u0622\u0646\u0647\u0627 \u0628\u0627\u06cc\u062f \u0628\u0647 \u0639\u0646\u0648\u0627\u0646 \u0645\u062a\u062f\u0647\u0627\u06cc \u062c\u0632\u0621 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u0634\u0648\u0646\u062f\u060c <code>authenticate()<\/code> \u0648 <code>register()<\/code>.<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-comment\">&lt;!-- components\/Login.vue --&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>&gt;<\/span><span class=\"javascript\">\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> {\n  data () {\n    <span class=\"hljs-keyword\">return<\/span> {\n      <span class=\"hljs-attr\">email<\/span>: <span class=\"hljs-string\">''<\/span>,\n      <span class=\"hljs-attr\">password<\/span>: <span class=\"hljs-string\">''<\/span>,\n      <span class=\"hljs-attr\">errorMsg<\/span>: <span class=\"hljs-string\">''<\/span>\n    }\n  },\n  <span class=\"hljs-attr\">methods<\/span>: {\n    authenticate () {\n      <span class=\"hljs-built_in\">this<\/span>.$store.dispatch(<span class=\"hljs-string\">'login'<\/span>, { <span class=\"hljs-attr\">email<\/span>: <span class=\"hljs-built_in\">this<\/span>.email, <span class=\"hljs-attr\">password<\/span>: <span class=\"hljs-built_in\">this<\/span>.password })\n        .then(<span class=\"hljs-function\">() =&gt;<\/span> <span class=\"hljs-built_in\">this<\/span>.$router.push(<span class=\"hljs-string\">'\/'<\/span>))\n    },\n    register () {\n      <span class=\"hljs-built_in\">this<\/span>.$store.dispatch(<span class=\"hljs-string\">'register'<\/span>, { <span class=\"hljs-attr\">email<\/span>: <span class=\"hljs-built_in\">this<\/span>.email, <span class=\"hljs-attr\">password<\/span>: <span class=\"hljs-built_in\">this<\/span>.password })\n        .then(<span class=\"hljs-function\">() =&gt;<\/span> <span class=\"hljs-built_in\">this<\/span>.$router.push(<span class=\"hljs-string\">'\/'<\/span>))\n    }\n  },\n  mounted () {\n    EventBus.$\u0631\u0648\u06cc(<span class=\"hljs-string\">'failedRegistering'<\/span>, <span class=\"hljs-function\">(<span class=\"hljs-params\">msg<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-built_in\">this<\/span>.errorMsg = msg\n    })\n    EventBus.$\u0631\u0648\u06cc(<span class=\"hljs-string\">'failedAuthentication'<\/span>, <span class=\"hljs-function\">(<span class=\"hljs-params\">msg<\/span>) =&gt;<\/span> {\n      <span class=\"hljs-built_in\">this<\/span>.errorMsg = msg\n    })\n  },\n  beforeDestroy () {\n    EventBus.$off(<span class=\"hljs-string\">'failedRegistering'<\/span>)\n    EventBus.$off(<span class=\"hljs-string\">'failedAuthentication'<\/span>)\n  }\n}\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n<\/code><\/pre>\n<p>\u062e\u0648\u0628\u060c \u0627\u06a9\u0646\u0648\u0646 \u0641\u0642\u0637 \u0628\u0627\u06cc\u062f \u0628\u0647 \u0628\u0642\u06cc\u0647 \u0628\u0631\u0646\u0627\u0645\u0647 \u0627\u0637\u0644\u0627\u0639 \u062f\u0647\u0645 \u06a9\u0647 \u0645\u0624\u0644\u0641\u0647 Login \u0648\u062c\u0648\u062f \u062f\u0627\u0631\u062f.  \u0645\u0646 \u0627\u06cc\u0646 \u06a9\u0627\u0631 \u0631\u0627 \u0628\u0627 \u0648\u0627\u0631\u062f \u06a9\u0631\u062f\u0646 \u0622\u0646 \u062f\u0631 \u0645\u0627\u0698\u0648\u0644 \u0631\u0648\u062a\u0631 \u0648 \u062a\u0639\u0631\u06cc\u0641 \u0645\u0633\u06cc\u0631 \u0622\u0646 \u0627\u0646\u062c\u0627\u0645 \u0645\u06cc \u062f\u0647\u0645.  \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u0645\u0646 \u062f\u0631 \u0645\u0627\u0698\u0648\u0644 \u0631\u0648\u062a\u0631 \u0647\u0633\u062a\u0645\u060c \u0628\u0627\u06cc\u062f \u06cc\u06a9 \u062a\u063a\u06cc\u06cc\u0631 \u0627\u0636\u0627\u0641\u06cc \u062f\u0631 \u0622\u0646 \u0627\u06cc\u062c\u0627\u062f \u06a9\u0646\u0645 <code>NewSurvey<\/code> \u0645\u0633\u06cc\u0631 \u06a9\u0627\u0645\u067e\u0648\u0646\u0646\u062a \u0628\u0631\u0627\u06cc \u0645\u062d\u0627\u0641\u0638\u062a \u0627\u0632 \u062f\u0633\u062a\u0631\u0633\u06cc \u0622\u0646 \u0641\u0642\u0637 \u0628\u0647 \u06a9\u0627\u0631\u0628\u0631\u0627\u0646 \u062a\u0623\u06cc\u06cc\u062f \u0634\u062f\u0647 \u0645\u0627\u0646\u0646\u062f \u0634\u06a9\u0644 \u0632\u06cc\u0631:<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-comment\">\/\/ router\/index.js<\/span>\n<span class=\"hljs-keyword\">import<\/span> Vue <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'vue'<\/span>\n<span class=\"hljs-keyword\">import<\/span> Router <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'vue-router'<\/span>\n<span class=\"hljs-keyword\">import<\/span> Home <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@\/components\/Home'<\/span>\n<span class=\"hljs-keyword\">import<\/span> Survey <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@\/components\/Survey'<\/span>\n<span class=\"hljs-keyword\">import<\/span> NewSurvey <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@\/components\/NewSurvey'<\/span>\n<span class=\"hljs-keyword\">import<\/span> Login <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@\/components\/Login'<\/span>\n<span class=\"hljs-keyword\">import<\/span> store <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@\/store'<\/span>\n\nVue.use(Router)\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> <span class=\"hljs-keyword\">new<\/span> Router({\n  <span class=\"hljs-attr\">routes<\/span>: (\n    {\n      <span class=\"hljs-attr\">path<\/span>: <span class=\"hljs-string\">'\/'<\/span>,\n      <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'Home'<\/span>,\n      <span class=\"hljs-attr\">component<\/span>: Home\n    }, {\n      <span class=\"hljs-attr\">path<\/span>: <span class=\"hljs-string\">'\/surveys\/:id'<\/span>,\n      <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'Survey'<\/span>,\n      <span class=\"hljs-attr\">component<\/span>: Survey\n    }, {\n      <span class=\"hljs-attr\">path<\/span>: <span class=\"hljs-string\">'\/surveys'<\/span>,\n      <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'NewSurvey'<\/span>,\n      <span class=\"hljs-attr\">component<\/span>: NewSurvey,\n      beforeEnter (to, <span class=\"hljs-keyword\">from<\/span>, next) {\n        <span class=\"hljs-keyword\">if<\/span> (!store.getters.isAuthenticated) {\n          next(<span class=\"hljs-string\">'\/login'<\/span>)\n        } <span class=\"hljs-keyword\">else<\/span> {\n          next()\n        }\n      }\n    }, {\n      <span class=\"hljs-attr\">path<\/span>: <span class=\"hljs-string\">'\/login'<\/span>,\n      <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">'Login'<\/span>,\n      <span class=\"hljs-attr\">component<\/span>: Login\n    }\n  )\n})\n\n<\/code><\/pre>\n<p>\u062f\u0631 \u0627\u06cc\u0646\u062c\u0627 \u0642\u0627\u0628\u0644 \u0630\u06a9\u0631 \u0627\u0633\u062a \u06a9\u0647 \u0645\u0646 \u062f\u0631 \u062d\u0627\u0644 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0647\u0633\u062a\u0645 <code>vue-router<\/code>\u0646\u06af\u0647\u0628\u0627\u0646 \u0645\u0633\u06cc\u0631 <code>beforeEnter<\/code> \u0628\u0631\u0627\u06cc \u0628\u0631\u0631\u0633\u06cc \u0627\u06cc\u0646\u06a9\u0647 \u0622\u06cc\u0627 \u06a9\u0627\u0631\u0628\u0631 \u0641\u0639\u0644\u06cc \u0627\u0632 \u0637\u0631\u06cc\u0642 \u0622\u0646 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0634\u062f\u0647 \u0627\u0633\u062a \u06cc\u0627 \u062e\u06cc\u0631 <code>isAuthenticated<\/code> \u062f\u0631\u06cc\u0627\u0641\u062a \u06a9\u0646\u0646\u062f\u0647 \u0627\u0632 \u0641\u0631\u0648\u0634\u06af\u0627\u0647  \u0627\u06af\u0631 <code>isAuthenticated<\/code> false \u0631\u0627 \u0628\u0631\u0645\u06cc \u06af\u0631\u062f\u0627\u0646\u062f \u0633\u067e\u0633 \u0628\u0631\u0646\u0627\u0645\u0647 \u0631\u0627 \u0628\u0647 \u0644\u0627\u06af\u06cc\u0646 \u0647\u062f\u0627\u06cc\u062a \u0645\u06cc \u06a9\u0646\u0645 page.<\/p>\n<p>\u0628\u0627 \u06a9\u062f\u06af\u0630\u0627\u0631\u06cc \u0645\u0624\u0644\u0641\u0647 Login \u0648 \u062a\u0639\u06cc\u06cc\u0646 \u0645\u0633\u06cc\u0631 \u0622\u0646\u060c \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0645 \u0627\u0632 \u0637\u0631\u06cc\u0642 \u06cc\u06a9 \u0645\u0624\u0644\u0641\u0647 \u067e\u06cc\u0648\u0646\u062f \u0645\u0633\u06cc\u0631\u06cc\u0627\u0628 \u062f\u0631 \u0645\u0624\u0644\u0641\u0647 \u00ab\u0647\u062f\u0631\u00bb \u0628\u0647 \u0622\u0646 \u062f\u0633\u062a\u0631\u0633\u06cc \u062f\u0627\u0634\u062a\u0647 \u0628\u0627\u0634\u0645. <code>components\/Header.vue<\/code>.  \u0645\u0646 \u0628\u0647 \u0635\u0648\u0631\u062a \u0645\u0634\u0631\u0648\u0637 \u06cc\u0627 \u067e\u06cc\u0648\u0646\u062f \u0628\u0647 \u0631\u0627 \u0646\u0634\u0627\u0646 \u0645\u06cc \u062f\u0647\u0645 <code>NewSurvey<\/code> \u062c\u0632\u0621 \u06cc\u0627 <code>Login<\/code> \u062c\u0632\u0621 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 <code>isAuthenticated<\/code> \u0630\u062e\u06cc\u0631\u0647 \u06af\u06cc\u0631\u0646\u062f\u0647 \u06cc\u06a9 \u0628\u0627\u0631 \u062f\u06cc\u06af\u0631 \u062f\u0631 \u06cc\u06a9 \u0648\u06cc\u0698\u06af\u06cc \u0645\u062d\u0627\u0633\u0628\u0647 \u0634\u062f\u0647 \u062f\u0631 <code>Header<\/code> \u062c\u0632\u0621 \u0627\u0631\u062c\u0627\u0639 \u0634\u062f\u0647 \u062a\u0648\u0633\u0637 <code>v-if<\/code> \u0628\u062e\u0634\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc\u06cc \u0627\u0632 \u0627\u06cc\u0646 \u0642\u0628\u06cc\u0644:<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-comment\">&lt;!-- components\/Header.vue --&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">template<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">nav<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"navbar is-light\"<\/span> <span class=\"hljs-attr\">role<\/span>=<span class=\"hljs-string\">\"navigation\"<\/span> <span class=\"hljs-attr\">aria-label<\/span>=<span class=\"hljs-string\">\"main navigation\"<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"navbar-menu\"<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"navbar-start\"<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">router-link<\/span> <span class=\"hljs-attr\">to<\/span>=<span class=\"hljs-string\">\"\/\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"navbar-item\"<\/span>&gt;<\/span>\n        Home\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">router-link<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">router-link<\/span> <span class=\"hljs-attr\">v-if<\/span>=<span class=\"hljs-string\">\"isAuthenticated\"<\/span> <span class=\"hljs-attr\">to<\/span>=<span class=\"hljs-string\">\"\/surveys\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"navbar-item\"<\/span>&gt;<\/span>\n        Create Survey\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">router-link<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">router-link<\/span> <span class=\"hljs-attr\">v-if<\/span>=<span class=\"hljs-string\">\"!isAuthenticated\"<\/span> <span class=\"hljs-attr\">to<\/span>=<span class=\"hljs-string\">\"\/login\"<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"navbar-item\"<\/span>&gt;<\/span>\n        Login \/ Register\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">router-link<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">nav<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">template<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>&gt;<\/span><span class=\"javascript\">\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> {\n  <span class=\"hljs-attr\">computed<\/span>: {\n    isAuthenticated () {\n      <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-built_in\">this<\/span>.$store.getters.isAuthenticated\n    }\n  }\n}\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">style<\/span>&gt;<\/span>\n\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">style<\/span>&gt;<\/span>\n<\/code><\/pre>\n<p>\u0639\u0627\u0644\u06cc!  \u062d\u0627\u0644\u0627 \u0628\u0627\u0644\u0627\u062e\u0631\u0647 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0645 \u0633\u0631\u0648\u0631\u0647\u0627\u06cc \u062a\u0648\u0633\u0639\u0647\u200c\u062f\u0647\u0646\u062f\u0647 \u0631\u0627 \u0628\u0631\u0627\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 Flask \u0648 \u0628\u0631\u0646\u0627\u0645\u0647 Vue.js \u0641\u0639\u0627\u0644 \u06a9\u0646\u0645 \u0648 \u0622\u0632\u0645\u0627\u06cc\u0634 \u06a9\u0646\u0645 \u062a\u0627 \u0628\u0628\u06cc\u0646\u0645 \u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u0645 \u06cc\u06a9 \u06a9\u0627\u0631\u0628\u0631 \u062b\u0628\u062a \u0646\u0627\u0645 \u06a9\u0631\u062f\u0647 \u0648 \u0644\u0627\u06af\u06cc\u0646 \u06a9\u0646\u0645.<\/p>\n<p>\u0627\u0628\u062a\u062f\u0627 \u0633\u0631\u0648\u0631 \u062a\u0648\u0633\u0639\u0647 \u062f\u0647\u0646\u062f\u0647 Flask \u0631\u0627 \u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc \u0645\u06cc \u06a9\u0646\u0645.<\/p>\n<pre><code class=\"hljs\">(venv) $ python appserver.py\n<\/code><\/pre>\n<p>\u0633\u067e\u0633 \u0633\u0631\u0648\u0631 \u062a\u0648\u0633\u0639\u0647 \u062f\u0647\u0646\u062f\u0647 webpack \u0628\u0631\u0646\u0627\u0645\u0647 Vue.js \u0631\u0627 \u06a9\u0627\u0645\u067e\u0627\u06cc\u0644 \u0648 \u0627\u0631\u0627\u0626\u0647 \u0645\u06cc \u06a9\u0646\u062f.<\/p>\n<pre><code class=\"hljs\">$ npm run dev\n<\/code><\/pre>\n<p>\u062f\u0631 \u0645\u0631\u0648\u0631\u06af\u0631 \u0645\u0646 \u0628\u0627\u0632\u062f\u06cc\u062f \u0645\u06cc \u06a9\u0646\u0645 <code>http:\/\/localhost:8080<\/code> (\u06cc\u0627 \u0647\u0631 \u067e\u0648\u0631\u062a\u06cc \u06a9\u0647 \u0633\u0631\u0648\u0631 \u062a\u0648\u0633\u0639\u0647 \u062f\u0647\u0646\u062f\u0647 \u0648\u0628 \u067e\u06a9 \u0646\u0634\u0627\u0646 \u0645\u06cc \u062f\u0647\u062f) \u0648 \u0645\u0637\u0645\u0626\u0646 \u0634\u0648\u06cc\u062f \u06a9\u0647 \u0646\u0648\u0627\u0631 \u0646\u0627\u0648\u0628\u0631\u06cc \u0627\u06a9\u0646\u0648\u0646 &#8220;\u0648\u0631\u0648\u062f \/ \u062b\u0628\u062a \u0646\u0627\u0645&#8221; \u0631\u0627 \u062f\u0631 \u0645\u062d\u0644 &#8220;\u0627\u06cc\u062c\u0627\u062f \u0646\u0638\u0631\u0633\u0646\u062c\u06cc&#8221; \u0645\u0627\u0646\u0646\u062f \u0634\u06a9\u0644 \u0632\u06cc\u0631 \u0646\u0645\u0627\u06cc\u0634 \u0645\u06cc \u062f\u0647\u062f:<\/p>\n<p><img decoding=\"async\" class=\"img-responsive\" src=\"https:\/\/rasanegar.com\/blog\/wp-content\/uploads\/2024\/01\/single-page-apps-vue-and-flask-jwt-authentication-1.png\" alt=\"\u0646\u0648\u0627\u0631 \u0646\u0627\u0648\u0628\u0631\u06cc \u0648\u0627\u0631\u062f \u0634\u0648\u06cc\u062f\" title=\"\"><\/p>\n<p>\u0628\u0639\u062f \u06a9\u0644\u06cc\u06a9 \u0645\u06cc \u06a9\u0646\u0645 \u0631\u0648\u06cc \u067e\u06cc\u0648\u0646\u062f &#8220;\u0648\u0631\u0648\u062f \/ \u062b\u0628\u062a \u0646\u0627\u0645&#8221; \u0631\u0627 \u0648\u0627\u0631\u062f \u06a9\u0646\u06cc\u062f \u0648 \u0648\u0631\u0648\u062f\u06cc \u0647\u0627\u06cc \u0627\u06cc\u0645\u06cc\u0644 \u0648 \u0631\u0645\u0632 \u0639\u0628\u0648\u0631 \u0631\u0627 \u067e\u0631 \u06a9\u0646\u06cc\u062f\u060c \u0633\u067e\u0633 \u0631\u0648\u06cc \u062b\u0628\u062a \u06a9\u0644\u06cc\u06a9 \u06a9\u0646\u06cc\u062f \u062a\u0627 \u0645\u0637\u0645\u0626\u0646 \u0634\u0648\u06cc\u062f \u0645\u0637\u0627\u0628\u0642 \u0627\u0646\u062a\u0638\u0627\u0631 \u0639\u0645\u0644 \u0645\u06cc \u06a9\u0646\u062f \u0648 \u0645\u0646 \u0628\u0647 \u062e\u0627\u0646\u0647 \u0647\u062f\u0627\u06cc\u062a \u0645\u06cc \u0634\u0648\u0645. page \u0648 \u0644\u06cc\u0646\u06a9 &#8220;\u0627\u06cc\u062c\u0627\u062f \u0646\u0638\u0631\u0633\u0646\u062c\u06cc&#8221; \u0631\u0627 \u0628\u0628\u06cc\u0646\u06cc\u062f \u06a9\u0647 \u0628\u0647 \u062c\u0627\u06cc \u067e\u06cc\u0648\u0646\u062f &#8220;\u0648\u0631\u0648\u062f \/ \u062b\u0628\u062a \u0646\u0627\u0645&#8221; \u06a9\u0647 \u0642\u0628\u0644 \u0627\u0632 \u062b\u0628\u062a \u0646\u0627\u0645 \u0648\u062c\u0648\u062f \u062f\u0627\u0634\u062a\u060c \u0646\u0645\u0627\u06cc\u0634 \u062f\u0627\u062f\u0647 \u0634\u062f\u0647 \u0627\u0633\u062a.<\/p>\n<p><img decoding=\"async\" class=\"img-responsive\" src=\"https:\/\/rasanegar.com\/blog\/wp-content\/uploads\/2024\/01\/single-page-apps-vue-and-flask-jwt-authentication-2.png\" alt=\"\u0648\u0627\u0631\u062f \u0634\u062f\u0646 page\" title=\"\"><\/p>\n<p>\u062e\u0648\u0628\u060c \u06a9\u0627\u0631 \u0645\u0646 \u062a\u0627 \u062d\u062f \u0632\u06cc\u0627\u062f\u06cc \u0627\u0646\u062c\u0627\u0645 \u0634\u062f\u0647 \u0627\u0633\u062a.  \u062a\u0646\u0647\u0627 \u06a9\u0627\u0631\u06cc \u06a9\u0647 \u0628\u0627\u06cc\u062f \u0627\u0646\u062c\u0627\u0645 \u062f\u0647\u06cc\u062f \u0627\u06cc\u0646 \u0627\u0633\u062a \u06a9\u0647 \u06a9\u0645\u06cc \u0631\u0633\u06cc\u062f\u06af\u06cc \u0628\u0647 \u062e\u0637\u0627 \u0631\u0627 \u0628\u0647 \u0622\u0646 \u0627\u0636\u0627\u0641\u0647 \u06a9\u0646\u06cc\u062f <code>submitSurvey(...)<\/code> \u0631\u0648\u0634 Vue.js \u0627\u0632 <code>NewSurvey<\/code> \u0645\u0624\u0644\u0641\u0647 \u0627\u06cc \u0628\u0631\u0627\u06cc \u0631\u0633\u06cc\u062f\u06af\u06cc \u0628\u0647 \u0631\u0648\u06cc\u062f\u0627\u062f\u06cc \u06a9\u0647 \u062f\u0631 \u0622\u0646 \u062a\u0648\u06a9\u0646 \u0627\u062a\u0641\u0627\u0642\u06cc \u0645\u0646\u0642\u0636\u06cc \u0645\u06cc \u0634\u0648\u062f \u062f\u0631 \u062d\u0627\u0644\u06cc \u06a9\u0647 \u06a9\u0627\u0631\u0628\u0631 \u062f\u0631 \u062d\u0627\u0644 \u0627\u06cc\u062c\u0627\u062f \u06cc\u06a9 \u0646\u0638\u0631\u0633\u0646\u062c\u06cc \u062c\u062f\u06cc\u062f \u0645\u0627\u0646\u0646\u062f \u0627\u06cc\u0646 \u0627\u0633\u062a:<\/p>\n<pre><code class=\"hljs\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">script<\/span>&gt;<\/span><span class=\"javascript\">\n<span class=\"hljs-keyword\">import<\/span> NewQuestion <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@\/components\/NewQuestion'<\/span>\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">default<\/span> {\n  <span class=\"hljs-attr\">components<\/span>: { NewQuestion },\n  data () {\n    <span class=\"hljs-keyword\">return<\/span> {\n      <span class=\"hljs-attr\">step<\/span>: <span class=\"hljs-string\">'name'<\/span>,\n      <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-string\">''<\/span>,\n      <span class=\"hljs-attr\">questions<\/span>: ()\n    }\n  },\n  <span class=\"hljs-attr\">methods<\/span>: {\n\n    <span class=\"hljs-comment\">\/\/<\/span>\n    <span class=\"hljs-comment\">\/\/ omitting other methods<\/span>\n    <span class=\"hljs-comment\">\/\/<\/span>\n\n    submitSurvey () {\n      <span class=\"hljs-built_in\">this<\/span>.$store.dispatch(<span class=\"hljs-string\">'submitNewSurvey'<\/span>, {\n        <span class=\"hljs-attr\">name<\/span>: <span class=\"hljs-built_in\">this<\/span>.name,\n        <span class=\"hljs-attr\">questions<\/span>: <span class=\"hljs-built_in\">this<\/span>.questions\n      })\n        .then(<span class=\"hljs-function\">() =&gt;<\/span> <span class=\"hljs-built_in\">this<\/span>.$router.push(<span class=\"hljs-string\">'\/'<\/span>))\n        .catch(<span class=\"hljs-function\">(<span class=\"hljs-params\">error<\/span>) =&gt;<\/span> {\n          <span class=\"hljs-built_in\">console<\/span>.log(<span class=\"hljs-string\">'Error creating survey'<\/span>, error)\n          <span class=\"hljs-built_in\">this<\/span>.$router.push(<span class=\"hljs-string\">'\/'<\/span>)\n        })\n    }\n  }\n}\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">script<\/span>&gt;<\/span>\n<\/code><\/pre>\n<h2 id=\"resources\"><span class=\"ez-toc-section\" id=\"%d9%85%d9%86%d8%a7%d8%a8%d8%b9\"><\/span>\u0645\u0646\u0627\u0628\u0639<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u0622\u06cc\u0627 \u0645\u06cc \u062e\u0648\u0627\u0647\u06cc\u062f \u062f\u0631 \u0645\u0648\u0631\u062f \u0686\u0627\u0631\u0686\u0648\u0628 \u0647\u0627\u06cc \u0645\u062e\u062a\u0644\u0641 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0634\u062f\u0647 \u062f\u0631 \u0627\u06cc\u0646 \u0645\u0642\u0627\u0644\u0647 \u0628\u06cc\u0634\u062a\u0631 \u0628\u062f\u0627\u0646\u06cc\u062f\u061f  \u0628\u0631\u062e\u06cc \u0627\u0632 \u0645\u0646\u0627\u0628\u0639 \u0632\u06cc\u0631 \u0631\u0627 \u0628\u0631\u0627\u06cc \u0628\u0631\u0631\u0633\u06cc \u0639\u0645\u06cc\u0642 \u062a\u0631 \u062f\u0631 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Vue.js \u06cc\u0627 \u0633\u0627\u062e\u062a\u0646 API\u0647\u0627\u06cc \u0628\u06a9\u200c\u0627\u0646\u062f \u062f\u0631 \u067e\u0627\u06cc\u062a\u0648\u0646 \u0628\u0631\u0631\u0633\u06cc \u06a9\u0646\u06cc\u062f:<\/p>\n<ul>\n<li><a class=\"udemy-link\" rel=\"nofollow noopener\" target=\"_blank\" href=\"http:\/\/stackabu.se\/rest-apis-flask-python\">REST API\u0647\u0627 \u0628\u0627 Flask \u0648 Python<\/a><\/li>\n<li><a class=\"udemy-link\" rel=\"nofollow noopener\" target=\"_blank\" href=\"http:\/\/stackabu.se\/vue-js-2-complete-guide\">Vue.js 2 &#8211; \u0631\u0627\u0647\u0646\u0645\u0627\u06cc \u06a9\u0627\u0645\u0644<\/a><\/li>\n<li><a class=\"udemy-link\" rel=\"nofollow noopener\" target=\"_blank\" href=\"http:\/\/stackabu.se\/ultimate-vue-js-2-developers-course\">\u062f\u0648\u0631\u0647 \u062a\u0648\u0633\u0639\u0647 \u062f\u0647\u0646\u062f\u06af\u0627\u0646 Ultimate Vue JS 2<\/a><\/li>\n<\/ul>\n<h2 id=\"conclusion\"><span class=\"ez-toc-section\" id=\"%d9%86%d8%aa%db%8c%d8%ac%d9%87\"><\/span>\u0646\u062a\u06cc\u062c\u0647<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>\u062f\u0631 \u0627\u06cc\u0646 \u067e\u0633\u062a \u0631\u0648\u0634 \u067e\u06cc\u0627\u062f\u0647 \u0633\u0627\u0632\u06cc \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a JWT \u0631\u0627 \u062f\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0646\u0638\u0631\u0633\u0646\u062c\u06cc \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Vue.js \u0648 Flask \u0646\u0634\u0627\u0646 \u062f\u0627\u062f\u0645.  JWT \u06cc\u06a9 \u0631\u0648\u0634 \u0645\u062d\u0628\u0648\u0628 \u0648 \u0642\u0648\u06cc \u0628\u0631\u0627\u06cc \u0627\u0631\u0627\u0626\u0647 \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u062f\u0631 \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc SPA \u0627\u0633\u062a\u060c \u0648 \u0627\u0645\u06cc\u062f\u0648\u0627\u0631\u0645 \u067e\u0633 \u0627\u0632 \u062e\u0648\u0627\u0646\u062f\u0646 \u0627\u06cc\u0646 \u067e\u0633\u062a \u0627\u062d\u0633\u0627\u0633 \u0631\u0627\u062d\u062a\u06cc \u06a9\u0646\u06cc\u062f \u06a9\u0647 \u0627\u0632 \u0627\u06cc\u0646 \u0641\u0646\u0627\u0648\u0631\u06cc \u0647\u0627 \u0628\u0631\u0627\u06cc \u0627\u06cc\u0645\u0646 \u0633\u0627\u0632\u06cc \u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc \u062e\u0648\u062f \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u06a9\u0646\u06cc\u062f.  \u0628\u0627 \u0627\u06cc\u0646 \u062d\u0627\u0644\u060c \u062a\u0648\u0635\u06cc\u0647 \u0645\u06cc \u06a9\u0646\u0645 \u0628\u0631\u0627\u06cc \u062f\u0631\u06a9 \u0639\u0645\u06cc\u0642 \u062a\u0631 \u0627\u0632 \u0686\u06af\u0648\u0646\u06af\u06cc \u0648 \u0686\u0631\u0627\u06cc\u06cc \u06a9\u0627\u0631 JWT\u060c \u0627\u0632 \u0645\u0642\u0627\u0644\u0647 rasanegar \u0627\u0633\u06a9\u0627\u062a \u062f\u06cc\u062f\u0646 \u06a9\u0646\u06cc\u062f.<\/p>\n<p>\u0645\u062b\u0644 \u0647\u0645\u06cc\u0634\u0647\u060c \u0645\u0645\u0646\u0648\u0646 \u06a9\u0647 \u062e\u0648\u0627\u0646\u062f\u06cc\u062f \u0648 \u0627\u0632 \u0646\u0638\u0631 \u062f\u0627\u062f\u0646 \u06cc\u0627 \u0627\u0646\u062a\u0642\u0627\u062f \u062f\u0631 \u0632\u06cc\u0631 \u062e\u062c\u0627\u0644\u062a \u0646\u06a9\u0634\u06cc\u062f.<\/p>\n<\/div>\n<p>    (\u0628\u0631\u0686\u0633\u0628\u200c\u0647\u0627 \u0628\u0647 \u062a\u0631\u062c\u0645\u0647)# python<br \/>\n<br \/><br \/>\n<br \/>\u0645\u0646\u062a\u0634\u0631 \u0634\u062f\u0647 \u062f\u0631 1403-01-26 19:42:06<br \/>\n<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-center kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;center&quot;,&quot;id&quot;:&quot;16547&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;0&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;0&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;5&quot;,&quot;greet&quot;:&quot;\u0627\u0645\u062a\u06cc\u0627\u0632 \u0634\u0645\u0627 \u0628\u0647 \u0627\u06cc\u0646 \u0645\u0637\u0644\u0628&quot;,&quot;legend&quot;:&quot;0\\\/5 (0 \u0631\u0627\u06cc)&quot;,&quot;size&quot;:&quot;30&quot;,&quot;title&quot;:&quot;\u0628\u0631\u0646\u0627\u0645\u0647 \u0647\u0627\u06cc \u062a\u06a9 \u0635\u0641\u062d\u0647 \u0627\u06cc \u0628\u0627 Vue.js \u0648 Flask: JWT Authentication \u0628\u0647 \u0642\u0633\u0645\u062a \u0634\u0634\u0645 \u0627\u06cc\u0646 \u0645\u062c\u0645\u0648\u0639\u0647 \u0622\u0645\u0648\u0632\u0634\u06cc \u0686\u0646\u062f \u0642\u0633\u0645\u062a\u06cc \u062e\u0648\u0634 \u0622\u0645\u062f\u06cc\u062f \u0631\u0648\u06cc \u062a\u0648\u0633\u0639\u0647 \u0648\u0628 \u062a\u0645\u0627\u0645 \u067e\u0634\u062a\u0647 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Vue.js \u0648 Flask.  \u062f\u0631 \u0627\u06cc\u0646 \u067e\u0633\u062a \u0645\u0646 \u0631\u0648\u0634\u06cc \u0628\u0631\u0627\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 JSON Web Token (JWT) \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0631\u0627 \u0646\u0634\u0627\u0646 \u062e\u0648\u0627\u0647\u0645 \u062f\u0627\u062f.  \u06a9\u062f \u0627\u06cc\u0646 \u067e\u0633\u062a \u0631\u0627 \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u067e\u06cc\u062f\u0627 \u06a9\u0646\u06cc\u062f \u0631\u0648\u06cc \u062d\u0633\u0627\u0628 GitHub \u0645\u0646 \u062f\u0631 \u0632\u06cc\u0631 \u0634\u0627\u062e\u0647 ...&quot;,&quot;width&quot;:&quot;0&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ({count} \u0631\u0627\u06cc)&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-left: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-left: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-left: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-left: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-left: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 0px;\">\n            <div class=\"kksr-star\" style=\"padding-left: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-left: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-left: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-left: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-left: 5px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 30px; height: 30px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 24px;\">\n            <span class=\"kksr-muted\">\u0627\u0645\u062a\u06cc\u0627\u0632 \u0634\u0645\u0627 \u0628\u0647 \u0627\u06cc\u0646 \u0645\u0637\u0644\u0628<\/span>\n    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">\u0632\u0645\u0627\u0646 \u0644\u0627\u0632\u0645 \u0628\u0631\u0627\u06cc \u0645\u0637\u0627\u0644\u0639\u0647: <\/span> <span class=\"rt-time\"> 15<\/span> <span class=\"rt-label rt-postfix\">\u062f\u0642\u06cc\u0642\u0647<\/span><\/span>\u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a JWT \u0628\u0647 \u0642\u0633\u0645\u062a \u0634\u0634\u0645 \u0627\u06cc\u0646 \u0645\u062c\u0645\u0648\u0639\u0647 \u0622\u0645\u0648\u0632\u0634\u06cc \u0686\u0646\u062f \u0642\u0633\u0645\u062a\u06cc \u062e\u0648\u0634 \u0622\u0645\u062f\u06cc\u062f \u0631\u0648\u06cc \u062a\u0648\u0633\u0639\u0647 \u0648\u0628 \u062a\u0645\u0627\u0645 \u067e\u0634\u062a\u0647 \u0628\u0627 \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 Vue.js \u0648 Flask. \u062f\u0631 \u0627\u06cc\u0646 \u067e\u0633\u062a \u0645\u0646 \u0631\u0648\u0634\u06cc \u0628\u0631\u0627\u06cc \u0627\u0633\u062a\u0641\u0627\u062f\u0647 \u0627\u0632 JSON Web Token (JWT) \u0627\u062d\u0631\u0627\u0632 \u0647\u0648\u06cc\u062a \u0631\u0627 \u0646\u0634\u0627\u0646 \u062e\u0648\u0627\u0647\u0645 \u062f\u0627\u062f. \u06a9\u062f \u0627\u06cc\u0646 \u067e\u0633\u062a \u0631\u0627 \u0645\u06cc \u062a\u0648\u0627\u0646\u06cc\u062f \u067e\u06cc\u062f\u0627 \u06a9\u0646\u06cc\u062f \u0631\u0648\u06cc \u062d\u0633\u0627\u0628 GitHub \u0645\u0646 \u062f\u0631 [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1772,620],"tags":[],"class_list":["post-16547","post","type-post","status-publish","format-standard","hentry","category-javascript","category-programming"],"acf":[],"_links":{"self":[{"href":"https:\/\/rasanegaar.com\/blog\/wp-json\/wp\/v2\/posts\/16547","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rasanegaar.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rasanegaar.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rasanegaar.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/rasanegaar.com\/blog\/wp-json\/wp\/v2\/comments?post=16547"}],"version-history":[{"count":0,"href":"https:\/\/rasanegaar.com\/blog\/wp-json\/wp\/v2\/posts\/16547\/revisions"}],"wp:attachment":[{"href":"https:\/\/rasanegaar.com\/blog\/wp-json\/wp\/v2\/media?parent=16547"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rasanegaar.com\/blog\/wp-json\/wp\/v2\/categories?post=16547"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rasanegaar.com\/blog\/wp-json\/wp\/v2\/tags?post=16547"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}