{"id":309053,"date":"2020-08-26T15:01:10","date_gmt":"2020-08-26T15:01:10","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=309053"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=309053","title":{"rendered":"Spring. \u041a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0441 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c JWT"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/516638\/\">\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f, \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0443\u0434\u0430\u0447\u043d\u044b\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0435\u0433\u043e \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430 \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 REST API \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c JWT.<br \/>  \u042d\u0442\u043e \u043d\u0435 \u0437\u0430\u043c\u0435\u043d\u0430 Spring Security, \u043d\u043e \u044d\u0442\u043e\u0442 \u0441\u043f\u043e\u0441\u043e\u0431 \u0445\u043e\u0440\u043e\u0448\u043e \u0441\u0435\u0431\u044f \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u043e\u0442 \u0443\u0436\u0435 \u0431\u043e\u043b\u0435\u0435 \u0434\u0432\u0443\u0445 \u043b\u0435\u0442. <\/p>\n<p>  \u041f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043b\u044e\u0447\u0430 \u0434\u043b\u044f JWT \u0434\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u0436\u0435 \u043d\u0435\u0437\u043d\u0430\u043a\u043e\u043c\u043e\u043c\u0443 \u0441 JWT \u0441\u0442\u0430\u043b\u043e \u0432\u0441\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ic\/tu\/lc\/ictulc2gaazjvhlv3ojnzbot0by.png\"\/><br \/>  <a name=\"habracut\"><\/a>  <\/p>\n<h2><font color=\"#292e5b\">\u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435<\/font><\/h2>\n<p>  <\/p>\n<ul>\n<li>\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f<\/li>\n<li>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043b\u044e\u0447\u0430<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 Spring \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/li>\n<li>TokenHandler<\/li>\n<li>\u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/li>\n<li>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 AuthenticationException<\/li>\n<li>\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440<\/li>\n<\/ul>\n<p>  <\/p>\n<h2><font color=\"#292e5b\">0. \u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f<\/font><\/h2>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430, \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043c\u0435\u043d\u044f \u043f\u043e\u0431\u0443\u0434\u0438\u043b\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b Spring Security. \u041a\u043e\u043c\u0443 \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043c\u043e\u0436\u0435\u0442 \u0441\u0440\u0430\u0437\u0443 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0433\u043b\u0430\u0432\u0435.<\/p>\n<p>  \u041a \u0442\u043e\u043c\u0443 \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0432 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0444\u0438\u0440\u043c\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0441\u0430\u0439\u0442\u043e\u0432. \u042d\u0442\u043e \u0431\u044b\u043b\u043e \u043c\u043e\u0435 \u043f\u0435\u0440\u0432\u043e\u0435 \u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u043c\u0435\u0441\u0442\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0444\u0435\u0440\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u043e\u043b\u043a\u043e\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u0438 \u043d\u0435 \u0437\u043d\u0430\u043b. \u0413\u0434\u0435-\u0442\u043e \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0441\u044f\u0446 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043a\u0430\u0437\u0430\u043b\u0438, \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0434\u043b\u044f \u043d\u0435\u0433\u043e. \u0420\u0435\u0448\u0438\u043b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043a\u0430\u043a \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0431\u044b\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u0432 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445. \u041a \u043c\u043e\u0435\u043c\u0443 \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0442\u0430\u043c \u0431\u044b\u043b\u043e \u0432\u0441\u0435 \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0438 \u0440\u0430\u0434\u043e\u0441\u0442\u043d\u043e. <\/p>\n<p>  \u0412 \u043a\u0430\u0436\u0434\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u0442\u0430\u043c \u0433\u0434\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u044b\u0442\u0430\u0449\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0431\u044b\u043b\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435<\/p>\n<pre><code class=\"java\">@RequestMapping(value = &quot;\/endpoint&quot;, method = RequestMethod.GET)  public Response endpoint() {      User user = getUser(); \/\/ \u041c\u0435\u0442\u043e\u0434 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430      if (null == user)          return new ErrorResponse.Builder(Error.AUTHENTICATION_ERROR).build();       \/\/ \u041b\u043e\u0433\u0438\u043a\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430  } <\/code><\/pre>\n<p>  \u0418 \u0442\u0430\u043a \u0431\u044b\u043b\u043e \u0432\u0435\u0437\u0434\u0435\u2026 \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u043b\u043e\u0441\u044c \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043b\u0441\u044f \u044d\u0442\u043e\u0442 \u043a\u0443\u0441\u043e\u043a \u043a\u043e\u0434\u0430. \u041c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u044d\u0442\u043e <s>\u043d\u0435\u043c\u043d\u043e\u0433\u043e<\/s> \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u043c \u0438 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u044b\u043c \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438.<\/p>\n<p>  \u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u044f \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b\u0441\u044f \u0432 \u0433\u0443\u0433\u043b. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u044f \u043a\u0430\u043a-\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0438\u0441\u043a\u0430\u043b, \u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b. \u0412\u0435\u0437\u0434\u0435 \u0431\u044b\u043b\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 Spring Security.<\/p>\n<p>  \u041e\u0431\u044a\u044f\u0441\u043d\u044e \u043f\u043e\u0447\u0435\u043c\u0443 \u044f \u043d\u0435 \u0445\u043e\u0442\u0435\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Spring Security. \u041e\u043d \u043c\u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u043b\u043e\u0436\u043d\u044b\u043c \u0438 \u0435\u0433\u043e \u043a\u0430\u043a-\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 REST. \u0414\u0430 \u0438 \u0432 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 endpoint&#8217;\u0430 \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c \u044e\u0437\u0435\u0440\u0430 \u0438\u0437 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u044f \u043d\u0435 \u043f\u0440\u0430\u0432, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0435 \u0441\u0438\u043b\u044c\u043d\u043e \u0432 \u043d\u0435\u043c \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043b\u0441\u044f, \u043d\u043e \u0441\u0442\u0430\u0442\u044c\u044f \u0432 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c.<\/p>\n<p>  \u041c\u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0447\u0442\u043e-\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0438 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438. \u041f\u0440\u0438\u0448\u043b\u0430 \u0438\u0434\u0435\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0447\u0435\u0440\u0435\u0437 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e.<\/p>\n<p>  \u0418\u0434\u0435\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u0433\u0434\u0435 \u043d\u0443\u0436\u043d\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f, \u043c\u044b \u0438\u043d\u0436\u0435\u043a\u0442\u0438\u043c \u043d\u0430\u0448\u0435\u0433\u043e \u044e\u0437\u0435\u0440\u0430. \u0418 \u0432\u0441\u0435. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0443\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u044e\u0437\u0435\u0440 \u0438 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 <b><i>!= null<\/i><\/b> (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435\u0432, \u043a\u043e\u0433\u0434\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f). <\/p>\n<p>  \u0421 \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c. \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435.<\/p>\n<h2><font color=\"#292e5b\">1. \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043b\u044e\u0447\u0430<\/font><\/h2>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0431\u0443\u0434\u0435\u0442 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u044e\u0437\u0435\u0440\u0435.<\/p>\n<p>  \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430 java \u0441 jwt \u0435\u0441\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u0430\u044f <a href=\"https:\/\/github.com\/jwtk\/jjwt\">\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430<\/a>.<\/p>\n<p>  \u041d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435 \u0435\u0441\u0442\u044c \u0432\u0441\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 jwt, \u043d\u043e \u0447\u0442\u043e \u0431\u044b \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0438\u0436\u0435.<\/p>\n<p>  \u0414\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043b\u044e\u0447\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 maven \u043f\u0440\u043e\u0435\u043a\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">dependencies<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">&lt;dependency&gt;     &lt;groupId&gt;io.jsonwebtoken&lt;\/groupId&gt;     &lt;artifactId&gt;jjwt-api&lt;\/artifactId&gt;     &lt;version&gt;0.11.2&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt;     &lt;groupId&gt;io.jsonwebtoken&lt;\/groupId&gt;     &lt;artifactId&gt;jjwt-impl&lt;\/artifactId&gt;     &lt;version&gt;0.11.2&lt;\/version&gt;     &lt;scope&gt;runtime&lt;\/scope&gt; &lt;\/dependency&gt; &lt;dependency&gt;     &lt;groupId&gt;io.jsonwebtoken&lt;\/groupId&gt;     &lt;artifactId&gt;jjwt-jackson&lt;\/artifactId&gt;     &lt;version&gt;0.11.2&lt;\/version&gt;     &lt;scope&gt;runtime&lt;\/scope&gt; &lt;\/dependency&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0418 \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c secret<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">SecretGenerator.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package jwt;  import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.io.Encoders; import io.jsonwebtoken.security.Keys;  import javax.crypto.SecretKey;  public class SecretGenerator {      public static void main(String[] args) {         SecretKey secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS512);         String secretString = Encoders.BASE64.encode(secretKey.getEncoded());         System.out.println(secretString);     } } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u043b\u044e\u0447, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<h2><font color=\"#292e5b\">2. \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 Spring \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/font><\/h2>\n<p>  \u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0443, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430 \u044d\u0442\u0443 \u0442\u0435\u043c\u0443 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u0442\u0430\u0442\u0435\u0439 \u0438 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u043e\u0432. \u0414\u0430 \u0438 \u043d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435 Spring&#8217;\u0430 \u0435\u0441\u0442\u044c <a href=\"https:\/\/start.spring.io\/\">initializer<\/a>, \u0433\u0434\u0435 \u0432 \u0434\u0432\u0430 \u043a\u043b\u0438\u043a\u0430 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442.<\/p>\n<p>  \u041e\u0441\u0442\u0430\u0432\u043b\u044e \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u0439 <i>pom<\/i> \u0444\u0430\u0439\u043b<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">pom.xml<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"xml\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt; &lt;project xmlns=&quot;http:\/\/maven.apache.org\/POM\/4.0.0&quot;          xmlns:xsi=&quot;http:\/\/www.w3.org\/2001\/XMLSchema-instance&quot;          xsi:schemaLocation=&quot;http:\/\/maven.apache.org\/POM\/4.0.0 http:\/\/maven.apache.org\/xsd\/maven-4.0.0.xsd&quot;&gt;     &lt;modelVersion&gt;4.0.0&lt;\/modelVersion&gt;      &lt;parent&gt;         &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;         &lt;artifactId&gt;spring-boot-starter-parent&lt;\/artifactId&gt;         &lt;version&gt;2.3.2.RELEASE&lt;\/version&gt;     &lt;\/parent&gt;      &lt;groupId&gt;org.website&lt;\/groupId&gt;     &lt;artifactId&gt;backend&lt;\/artifactId&gt;     &lt;version&gt;1.0-SNAPSHOT&lt;\/version&gt;     &lt;packaging&gt;jar&lt;\/packaging&gt;      &lt;properties&gt;         &lt;java.version&gt;14&lt;\/java.version&gt;         &lt;start-class&gt;org.website.BackendWebsiteApplication&lt;\/start-class&gt;     &lt;\/properties&gt;      &lt;profiles&gt;         &lt;profile&gt;             &lt;id&gt;local&lt;\/id&gt;             &lt;properties&gt;                 &lt;activatedProperties&gt;local&lt;\/activatedProperties&gt;             &lt;\/properties&gt;             &lt;activation&gt;                 &lt;activeByDefault&gt;true&lt;\/activeByDefault&gt;             &lt;\/activation&gt;         &lt;\/profile&gt;     &lt;\/profiles&gt;      &lt;build&gt;         &lt;plugins&gt;             &lt;plugin&gt;                 &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;                 &lt;artifactId&gt;spring-boot-maven-plugin&lt;\/artifactId&gt;             &lt;\/plugin&gt;         &lt;\/plugins&gt;     &lt;\/build&gt;      &lt;dependencies&gt;         &lt;!--*******SPRING*******--&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;             &lt;artifactId&gt;spring-boot-starter-web&lt;\/artifactId&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;             &lt;artifactId&gt;spring-boot-starter-logging&lt;\/artifactId&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;             &lt;artifactId&gt;spring-boot-starter-data-jpa&lt;\/artifactId&gt;         &lt;\/dependency&gt;          &lt;!--*******JWT*******--&gt;         &lt;dependency&gt;             &lt;groupId&gt;io.jsonwebtoken&lt;\/groupId&gt;             &lt;artifactId&gt;jjwt-api&lt;\/artifactId&gt;             &lt;version&gt;0.11.2&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;io.jsonwebtoken&lt;\/groupId&gt;             &lt;artifactId&gt;jjwt-impl&lt;\/artifactId&gt;             &lt;version&gt;0.11.2&lt;\/version&gt;             &lt;scope&gt;runtime&lt;\/scope&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;io.jsonwebtoken&lt;\/groupId&gt;             &lt;artifactId&gt;jjwt-jackson&lt;\/artifactId&gt;             &lt;version&gt;0.11.2&lt;\/version&gt;             &lt;scope&gt;runtime&lt;\/scope&gt;         &lt;\/dependency&gt;          &lt;!--*******OTHER*******--&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.postgresql&lt;\/groupId&gt;             &lt;artifactId&gt;postgresql&lt;\/artifactId&gt;             &lt;version&gt;42.2.14&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.liquibase&lt;\/groupId&gt;             &lt;artifactId&gt;liquibase-core&lt;\/artifactId&gt;             &lt;version&gt;4.0.0&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;com.google.guava&lt;\/groupId&gt;             &lt;artifactId&gt;guava&lt;\/artifactId&gt;             &lt;version&gt;29.0-jre&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;com.google.code.gson&lt;\/groupId&gt;             &lt;artifactId&gt;gson&lt;\/artifactId&gt;             &lt;version&gt;2.8.6&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.apache.commons&lt;\/groupId&gt;             &lt;artifactId&gt;commons-lang3&lt;\/artifactId&gt;             &lt;version&gt;3.11&lt;\/version&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.projectlombok&lt;\/groupId&gt;             &lt;artifactId&gt;lombok&lt;\/artifactId&gt;             &lt;version&gt;1.18.12&lt;\/version&gt;             &lt;scope&gt;provided&lt;\/scope&gt;         &lt;\/dependency&gt;          &lt;!--*******TEST*******--&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.junit.jupiter&lt;\/groupId&gt;             &lt;artifactId&gt;junit-jupiter&lt;\/artifactId&gt;             &lt;scope&gt;test&lt;\/scope&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;             &lt;artifactId&gt;spring-boot-starter-test&lt;\/artifactId&gt;             &lt;scope&gt;test&lt;\/scope&gt;         &lt;\/dependency&gt;         &lt;dependency&gt;             &lt;groupId&gt;org.hamcrest&lt;\/groupId&gt;             &lt;artifactId&gt;hamcrest&lt;\/artifactId&gt;             &lt;version&gt;2.2&lt;\/version&gt;             &lt;scope&gt;test&lt;\/scope&gt;         &lt;\/dependency&gt;     &lt;\/dependencies&gt;  &lt;\/project&gt; <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u0432 <b>application.properties<\/b><\/p>\n<pre><code class=\"java\">app.api.jwtEncodedSecretKey=teTN1EmB5XADI5iV4daGVAQhBlTwLMAE+LlXZp1JPI2PoQOpgVksRqe79EGOc5opg+AmxOOmyk8q1RbfSWcOyg== <\/code><\/pre>\n<p>  <\/p>\n<h2><font color=\"#292e5b\">3. TokenHandler<\/font><\/h2>\n<p>  \u041d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0438\u0441 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438 \u0442\u043e\u043a\u0435\u043d\u043e\u0432. <\/p>\n<p>  \u0412 \u0442\u043e\u043a\u0435\u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u044e\u0437\u0435\u0440\u0435(\u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0433\u043e id) \u0438 \u0432\u0440\u0435\u043c\u044f \u0438\u0441\u0442\u0435\u0447\u0435\u043d\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b.<\/p>\n<p>  \u0414\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0436\u0438\u0437\u043d\u0438 \u0442\u043e\u043a\u0435\u043d\u0430. <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">Expiration.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.jwt;  import java.time.LocalDateTime; import java.util.Optional;  public interface Expiration {      Optional&lt;LocalDateTime&gt; getAuthTokenExpire(); } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0418 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 ID. \u0415\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u044e\u0437\u0435\u0440\u0430<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">CreateBy.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.jwt;  public interface CreateBy {      Long getId(); } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0422\u0430\u043a \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u0443\u044e \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <b>Expiration<\/b>. \u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0442\u043e\u043a\u0435\u043d \u0431\u0443\u0434\u0435\u0442 \u0436\u0438\u0442\u044c 24 \u0447\u0430\u0441\u0430.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">DefaultExpiration.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.jwt;  import org.springframework.stereotype.Component;  import java.time.LocalDateTime; import java.util.Optional;  @Component public class DefaultExpiration implements Expiration {      @Override     public Optional&lt;LocalDateTime&gt; getAuthTokenExpire() {         return Optional.of(LocalDateTime.now().plusHours(24));     } } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0430\u0440\u0443 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432.<\/p>\n<p>  <b>GeneratedTokenInfo<\/b> \u2014 \u0434\u043b\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0442\u043e\u043a\u0435\u043d\u0435.<br \/>  <b>TokenInfo<\/b> \u2014 \u0434\u043b\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0435\u043c \u043a \u043d\u0430\u043c \u0442\u043e\u043a\u0435\u043d\u0435.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">GeneratedTokenInfo.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.jwt;  import java.time.LocalDateTime; import java.util.Optional;  public class GeneratedTokenInfo {      private final String token;     private final LocalDateTime expiration;      public GeneratedTokenInfo(String token, LocalDateTime expiration) {         this.token = token;         this.expiration = expiration;     }      public String getToken() {         return token;     }      public LocalDateTime getExpiration() {         return expiration;     }      public Optional&lt;String&gt; getSignature() {         if (null != this.token && this.token.length() &gt;= 3)             return Optional.of(this.token.split(&quot;\\\\.&quot;)[2]);          return Optional.empty();     } }  <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">TokenInfo.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.jwt;  import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jws; import lombok.NonNull;  import java.time.LocalDateTime; import java.time.ZoneId;  public class TokenInfo {      private final Jws&lt;Claims&gt; claimsJws;      private final String signature;     private final Claims body;     private final Long userId;     private final LocalDateTime expiration;      private TokenInfo() {         throw new UnsupportedOperationException();     }      private TokenInfo(@NonNull final Jws&lt;Claims&gt; claimsJws,                       @NonNull final String signature,                       @NonNull final Claims body,                       @NonNull final Long userId,                       @NonNull final LocalDateTime expiration) {         this.claimsJws = claimsJws;         this.signature = signature;         this.body = body;         this.userId = userId;         this.expiration = expiration;     }      public static TokenInfo fromClaimsJws(@NonNull final Jws&lt;Claims&gt; claimsJws) {         final Claims body = claimsJws.getBody();         return new TokenInfo(                 claimsJws,                 claimsJws.getSignature(),                 body,                 Long.parseLong(body.getId()),                 body.getExpiration().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());     }      public Jws&lt;Claims&gt; getClaimsJws() {         return claimsJws;     }      public String getSignature() {         return signature;     }      public Claims getBody() {         return body;     }      public Long getUserId() {         return userId;     }      public LocalDateTime getExpiration() {         return expiration;     } } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c <b>TokenHandler<\/b>. \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d \u043f\u0440\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u044e\u0437\u0435\u0440\u0430, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u043e\u043a\u0435\u043d\u0435 \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043f\u0440\u0438\u0448\u0435\u043b \u0440\u0430\u043d\u0435\u0435 \u0443\u0436\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u044e\u0437\u0435\u0440.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">TokenHandler.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.jwt;  import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service;  import javax.annotation.PostConstruct; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.sql.Date; import java.time.LocalDateTime; import java.time.ZoneId; import java.util.Base64; import java.util.Optional;  @Service @Slf4j public class TokenHandler {      @Value(&quot;${app.api.jwtEncodedSecretKey}&quot;)     private String jwtEncodedSecretKey;      private final DefaultExpiration defaultExpiration;      private SecretKey secretKey;      @Autowired     public TokenHandler(final DefaultExpiration defaultExpiration) {         this.defaultExpiration = defaultExpiration;     }      @PostConstruct     private void postConstruct() {         byte[] decode = Base64.getDecoder().decode(jwtEncodedSecretKey);         this.secretKey = new SecretKeySpec(decode, 0, decode.length, &quot;HmacSHA512&quot;);     }      public Optional&lt;GeneratedTokenInfo&gt; generateToken(CreateBy createBy, Expiration expire) {         if (null == expire || expire.getAuthTokenExpire().isEmpty())             expire = this.defaultExpiration;          try {             final LocalDateTime expireDateTime = expire.getAuthTokenExpire().get().withNano(0);              String compact = Jwts.builder()                     .setId(String.valueOf(createBy.getId()))                     .setExpiration(Date.from(expireDateTime.atZone(ZoneId.systemDefault()).toInstant()))                     .signWith(this.secretKey)                     .compact();              return Optional.of(new GeneratedTokenInfo(compact, expireDateTime));         } catch (Exception e) {             log.error(&quot;Error generate new token. CreateByID: {}; Message: {}&quot;, createBy.getId(), e.getMessage());         }         return Optional.empty();     }      public Optional&lt;GeneratedTokenInfo&gt; generateToken(CreateBy createBy) {         return this.generateToken(createBy, this.defaultExpiration);     }      public Optional&lt;TokenInfo&gt; extractTokenInfo(final String token) {         try {             Jws&lt;Claims&gt; claimsJws = Jwts.parserBuilder()                     .setSigningKey(this.secretKey)                     .build()                     .parseClaimsJws(token);             return Optional.ofNullable(claimsJws).map(TokenInfo::fromClaimsJws);         } catch (Exception e) {             log.error(&quot;Error extract token info. Message: {}&quot;, e.getMessage());         }          return Optional.empty();     }  } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0417\u0430\u043e\u0441\u0442\u0440\u044f\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0435 \u0431\u0443\u0434\u0443, \u0442\u0430\u043a \u043a\u0430\u043a \u0441 \u044d\u0442\u0438\u043c \u0432\u0441\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u043e. <\/p>\n<h2><font color=\"#292e5b\">4. \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a<\/font><\/h2>\n<p>  \u0418\u0442\u0430\u043a, \u043f\u043e\u0441\u043b\u0435 \u0432\u0441\u0435\u0445 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0440\u0430\u0431\u043e\u0442, \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u0430\u043c\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u043c\u0443. \u041a\u0430\u043a \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0440\u0430\u043d\u0435\u0435, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0442\u044c\u0441\u044f \u0432 \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u0433\u0434\u0435 \u043d\u0443\u0436\u0435\u043d \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c.<\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">AuthUser.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.annotation;  import java.lang.annotation.*;  @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface AuthUser {     boolean required() default true; } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0420\u0430\u043d\u0435\u0435 \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e, \u0447\u0442\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439. \u041a\u0430\u043a \u0440\u0430\u0437 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0438 \u043d\u0443\u0436\u0435\u043d \u043c\u0435\u0442\u043e\u0434 <b>required<\/b> \u0432 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430 \u0438 \u0435\u0441\u043b\u0438 \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d, \u0442\u043e \u0432 \u043c\u0435\u0442\u043e\u0434 \u0437\u0430\u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0442\u0441\u044f <b>null<\/b>. \u041d\u043e \u043a \u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0433\u043e\u0442\u043e\u0432\u044b.<\/p>\n<p>  \u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0430, \u043d\u043e \u0435\u0449\u0435 \u043d\u0443\u0436\u0435\u043d <b>handler<\/b>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0442\u043e\u043a\u0435\u043d, \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438\u0437 \u0431\u0430\u0437\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0440\u043e\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u0414\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u0443 Spring&#8217;\u0430 \u0435\u0441\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <b>HandlerMethodArgumentResolver<\/b>. \u0415\u0433\u043e \u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. <\/p>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441 <b>AuthUserHandlerMethodArgumentResolver<\/b>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0432\u044b\u0448\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">AuthUserHandlerMethodArgumentResolver.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.annotation.handler;  import org.springframework.core.MethodParameter; import org.springframework.lang.NonNull; import org.springframework.web.bind.support.WebArgumentResolver; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.util.WebUtils; import org.website.annotation.AuthUser; import org.website.annotation.exception.AuthenticationException; import org.website.domain.User; import org.website.domain.UserJwtSignature; import org.website.jwt.TokenHandler; import org.website.service.repository.UserJwtSignatureService;  import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import java.util.Objects; import java.util.Optional;  public class AuthUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {      private final String AUTH_COOKIE_NAME;     private final String AUTH_HEADER_NAME;      private final TokenHandler tokenHandler;      private final UserJwtSignatureService userJwtSignatureService;      public AuthUserHandlerMethodArgumentResolver(final String authTokenCookieName,                                                  final String authTokenHeaderName,                                                   final TokenHandler tokenHandler,                                                   final UserJwtSignatureService userJwtSignatureService) {         this.AUTH_COOKIE_NAME = authTokenCookieName;         this.AUTH_HEADER_NAME = authTokenHeaderName;          this.tokenHandler = tokenHandler;          this.userJwtSignatureService = userJwtSignatureService;     }      @Override     public boolean supportsParameter(@NonNull final MethodParameter methodParameter) {         return methodParameter.getParameterAnnotation(AuthUser.class) != null && methodParameter.getParameterType().equals(User.class);     }      @Override     public Object resolveArgument(@NonNull final MethodParameter methodParameter,                                   final ModelAndViewContainer modelAndViewContainer,                                   @NonNull final NativeWebRequest nativeWebRequest,                                   final WebDataBinderFactory webDataBinderFactory) throws Exception {         if (!this.supportsParameter(methodParameter))             return WebArgumentResolver.UNRESOLVED;          \/\/ \u0438\u0437 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f required         final boolean required = Objects.requireNonNull(methodParameter.getParameterAnnotation(AuthUser.class)).required();          \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c HttpServletRequest \u0438\u0437 \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430         Optional&lt;HttpServletRequest&gt; httpServletRequestOptional = Optional.ofNullable(nativeWebRequest.getNativeRequest(HttpServletRequest.class));          \/\/ \u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d \u0438\u0437 \u043a\u0443\u043a\u0438 \u0438\u043b\u0438 \u0438\u0437 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430         Optional&lt;UserJwtSignature&gt; userJwtSignature =                 this.extractAuthTokenFromRequest(nativeWebRequest, httpServletRequestOptional.orElse(null))                         .flatMap(tokenHandler::extractTokenInfo)                         .flatMap(userJwtSignatureService::extractByTokenInfo);                  if (required) {             \/\/ \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e             if (userJwtSignature.isEmpty() || null == userJwtSignature.get().getUser())                 \/\/ \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u043d\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435                 throw new AuthenticationException(httpServletRequestOptional.map(HttpServletRequest::getMethod).orElse(null),                         httpServletRequestOptional.map(HttpServletRequest::getRequestURI).orElse(null));              final User user = userJwtSignature.get().getUser();              \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u044e\u0437\u0435\u0440\u0430 \u0432 \u043c\u0435\u0442\u043e\u0434             return this.appendCurrentSignature(user, userJwtSignature.get());         } else {             \/\/ \u0435\u0441\u043b\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430, \u0442\u043e \u043b\u0438\u0431\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u044e\u0437\u0435\u0440\u0430, \u043b\u0438\u0431\u043e null             return this.appendCurrentSignature(userJwtSignature.map(UserJwtSignature::getUser).orElse(null),                     userJwtSignature.orElse(null));         }     }      private User appendCurrentSignature(User user, UserJwtSignature userJwtSignature) {         Optional.ofNullable(user).ifPresent(u -&gt; u.setCurrentSignature(userJwtSignature));         return user;     }      private Optional&lt;String&gt; extractAuthTokenFromRequest(@NonNull final NativeWebRequest nativeWebRequest,                                                          final HttpServletRequest httpServletRequest) {         return Optional.ofNullable(httpServletRequest)                 .flatMap(this::extractAuthTokenFromRequestByCookie)                 .or(() -&gt; this.extractAuthTokenFromRequestByHeader(nativeWebRequest));     }      private Optional&lt;String&gt; extractAuthTokenFromRequestByCookie(final HttpServletRequest httpServletRequest) {         return Optional                 .ofNullable(httpServletRequest)                 .map(request -&gt; WebUtils.getCookie(httpServletRequest, AUTH_COOKIE_NAME))                 .map(Cookie::getValue);     }      private Optional&lt;String&gt; extractAuthTokenFromRequestByHeader(@NonNull final NativeWebRequest nativeWebRequest) {         return Optional.ofNullable(nativeWebRequest.getHeader(AUTH_HEADER_NAME));     } } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0412 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043a\u0443\u043a\u0438 \u0438 \u0445\u0435\u0434\u0435\u0440\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u043a\u0435\u043d. \u042f \u0438\u0445 \u0432\u044b\u043d\u0435\u0441 \u0432 <b>application.properties<\/b><\/p>\n<pre><code class=\"java\">app.api.tokenKeyName=Auth-Token app.api.tokenHeaderName=Auth-Token <\/code><\/pre>\n<p>  \u0422\u0430\u043a \u0436\u0435 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 <b>TokenHandler<\/b> \u0438 <b>UserJwtSignatureService<\/b>.<\/p>\n<p>  UserJwtSignatureService \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0430\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u0437 \u0431\u0430\u0437\u044b \u043f\u043e \u0435\u0433\u043e id \u0438 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0435 \u0442\u043e\u043a\u0435\u043d\u0430. <\/p>\n<p>  \u0410 \u0432\u043e\u0442 \u043a\u043e\u0434 \u0441\u0430\u043c\u043e\u0433\u043e \u0445\u0435\u043d\u0434\u043b\u0435\u0440\u0430 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435.<\/p>\n<p>  <b>supportsParameter<\/b> \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u043b\u0438 \u043c\u0435\u0442\u043e\u0434 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u043c \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f\u043c.<\/p>\n<p>  <b>resolveArgument<\/b> \u2014 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043c\u0435\u0442\u043e\u0434, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u0441\u044f \u00ab\u043c\u0430\u0433\u0438\u044f\u00bb. <\/p>\n<p>  \u0418\u0442\u0430\u043a, \u0447\u0442\u043e \u0442\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442:<\/p>\n<ol>\n<li>\u0414\u043e\u0441\u0442\u0430\u0435\u043c \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f <i>required<\/i><\/li>\n<li>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c <i>HttpServletRequest<\/i> \u0438\u0437 \u043f\u0440\u0438\u0448\u0435\u0434\u0448\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/li>\n<li>\u041f\u0440\u043e\u0431\u0443\u0435\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d \u0438\u0437 \u043a\u0443\u043a\u0438 \u0438\u043b\u0438 \u0438\u0437 \u0445\u0435\u0434\u0435\u0440\u043e\u0432<\/li>\n<li>\u041f\u0430\u0440\u0441\u0438\u043c \u0435\u0433\u043e, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d \u0435\u0441\u0442\u044c<\/li>\n<li>\u0414\u043e\u0441\u0442\u0430\u0435\u043c \u0438\u0437 \u0431\u0430\u0437\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u0442\u043e\u043a\u0435\u043d\u0443<\/li>\n<li>\u0414\u0430\u043b\u0435\u0435 \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f <i>required<\/i>, \u0438 \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435, \u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. <br \/>  \u0412 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043c\u044b \u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0442\u043e \u0431\u0440\u043e\u0441\u0430\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435(\u0434\u043b\u044f \u0447\u0435\u0433\u043e \u044d\u0442\u043e \u043d\u0430\u0434\u043e, \u043e\u0431\u044a\u044f\u0441\u043d\u044e \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435). <br \/>  \u0415\u0441\u043b\u0438 \u0436\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u0442\u043e\u043a\u0435\u043d\u0443, \u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0435\u0433\u043e, \u0438 \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0438\u043d\u0436\u0435\u043a\u0447\u0435\u043d \u0432 \u043d\u0430\u0448 \u043c\u0435\u0442\u043e\u0434.<\/li>\n<li>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f, \u043e \u0447\u0435\u043c \u0441\u0432\u0438\u0434\u0435\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u043b\u0435 <i>required<\/i>, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043b\u0438\u0431\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u044e\u0437\u0435\u0440\u0430, \u043b\u0438\u0431\u043e null<\/li>\n<\/ol>\n<p>  \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u043d. \u041d\u043e \u044d\u0442\u043e \u0435\u0449\u0435 \u043d\u0435 \u0432\u0441\u0435. \u0415\u0433\u043e \u043d\u0430\u0434\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b Spring \u043e \u043d\u0435\u043c \u0443\u0437\u043d\u0430\u043b. \u0422\u0443\u0442 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e. \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Spring&#8217;\u0430 <b>WebMvcConfigurer<\/b> \u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <b>addArgumentResolvers<\/b><\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">WebMvcConfig.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.configuration;  import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.website.annotation.handler.AuthUserHandlerMethodArgumentResolver; import org.website.jwt.TokenHandler; import org.website.service.repository.UserJwtSignatureService;  import java.util.List;  @Configuration @EnableWebMvc public class WebMvcConfig implements WebMvcConfigurer {      @Value(&quot;${app.api.tokenKeyName}&quot;)     private String tokenKeyName;      @Value(&quot;${app.api.tokenHeaderName}&quot;)     private String tokenHeaderName;      private final TokenHandler tokenHandler;     private final UserJwtSignatureService userJwtSignatureService;      @Autowired     public WebMvcConfig(final TokenHandler tokenHandler,                         final UserJwtSignatureService userJwtSignatureService) {         this.tokenHandler = tokenHandler;         this.userJwtSignatureService = userJwtSignatureService;     }      @Override     public void addArgumentResolvers(List&lt;HandlerMethodArgumentResolver&gt; resolvers) {         resolvers.add(new AuthUserHandlerMethodArgumentResolver(                 this.tokenKeyName,                 this.tokenHeaderName,                 this.tokenHandler,                 this.userJwtSignatureService));     } } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u041d\u0430 \u044d\u0442\u043e\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<h2><font color=\"#292e5b\">5. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 AuthenticationException<\/font><\/h2>\n<p>  \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435, \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0435 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u0434\u043b\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430, \u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d \u043c\u044b \u0432\u044b\u0431\u0440\u043e\u0441\u0438\u043b\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 <b>AuthenticationException<\/b>. <\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0435\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e json \u0441 \u043d\u0443\u0436\u043d\u043e\u0439 \u043d\u0430\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">AuthenticationException.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.annotation.exception;  public class AuthenticationException extends Exception {      public AuthenticationException(String requestMethod, String url) {         super(String.format(&quot;%s - %s&quot;, requestMethod, url));     } } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0432\u043e\u0437\u043d\u0438\u043a\u0448\u0438\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043d\u0435 \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e Spring&#8217;\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435, \u0430 \u043d\u0443\u0436\u043d\u044b\u0439 \u043d\u0430\u043c json, \u0432 Spring&#8217;\u0435 \u0435\u0441\u0442\u044c \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f <b>ControllerAdvice<\/b>. <\/p>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043b\u0430\u0441\u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u044d\u043a\u0441\u0435\u043f\u0448\u0435\u043d\u0430.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">AuthenticationExceptionControllerAdvice.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.controller.exception.handler;  import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.website.annotation.exception.AuthenticationException; import org.website.http.response.Error; import org.website.http.response.ErrorResponse; import org.website.http.response.Response;  import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse;  @ControllerAdvice @Slf4j public class AuthenticationExceptionControllerAdvice extends AbstractControllerAdvice {      @Value(&quot;${app.api.tokenKeyName}&quot;)     private String tokenKeyName;      @ExceptionHandler({AuthenticationException.class})     public Response authenticationException(HttpServletResponse response) {         Cookie cookie = new Cookie(tokenKeyName, &quot;&quot;);         cookie.setPath(&quot;\/&quot;);         cookie.setMaxAge(0);         response.addCookie(cookie);         return new ErrorResponse.Builder(Error.AUTHENTICATION_ERROR).build();     } } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 <b>AuthenticationException<\/b>, \u043e\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0447\u0435\u043d\u043e \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f json \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439 <b>AUTHENTICATION_ERROR<\/b><\/p>\n<h2><font color=\"#292e5b\">6. \u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440<\/font><\/h2>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c, \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0440\u0430\u0434\u0438 \u0447\u0435\u0433\u043e \u0432\u0441\u0435 \u0438 \u0437\u0430\u0442\u0435\u0432\u0430\u043b\u043e\u0441\u044c. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 3 \u043c\u0435\u0442\u043e\u0434\u0430:<\/p>\n<ol>\n<li>\u0421 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0435\u0439<\/li>\n<li>\u0421 <b>\u043d\u0435<\/b>\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0435\u0439<\/li>\n<li>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u0434. \u041f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0431\u0430\u0437\u0443, \u0431\u0435\u0437 \u043f\u0430\u0440\u043e\u043b\u0435\u0439. \u041a\u043e\u0442\u043e\u0440\u044b\u0439, \u0442\u0430\u043a \u0436\u0435, \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/li>\n<\/ol>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">TestAuthController.java<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">package org.website.controller;  import com.google.gson.JsonObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.website.annotation.AuthUser; import org.website.domain.User; import org.website.http.response.Response; import org.website.http.response.SuccessResponse; import org.website.jwt.GeneratedTokenInfo; import org.website.service.repository.UserJwtSignatureService; import org.website.service.repository.UserService;  import java.util.Optional;  @RestController @RequestMapping(&quot;\/test-auth&quot;) public class TestAuthController {      @Autowired     private UserService userService;      @Autowired     private UserJwtSignatureService userJwtSignatureService;      @RequestMapping(value = &quot;\/required&quot;, method = RequestMethod.GET)     public Response required(@AuthUser final User user) {         return new SuccessResponse.Builder(user).build();     }      @RequestMapping(value = &quot;\/not-required&quot;, method = RequestMethod.GET)     public Response notRequired(@AuthUser(required = false) final User user) {         JsonObject response = new JsonObject();          if (null == user) {             response.addProperty(&quot;message&quot;, &quot;Hello guest!&quot;);         } else {             response.addProperty(&quot;message&quot;, &quot;Hello &quot; + user.getFirstName());         }          return new SuccessResponse.Builder(response).build();     }      @RequestMapping(value = &quot;\/sign-up&quot;, method = RequestMethod.GET)     public Response signUp(@RequestParam String firstName) {         User user = userService.save(User.builder().firstName(firstName).build());          Optional&lt;GeneratedTokenInfo&gt; generatedTokenInfoOptional =                 userJwtSignatureService.generateNewTokenAndSaveToDb(user);          return new SuccessResponse.Builder(user)                 .addPropertyToPayload(&quot;token&quot;, generatedTokenInfoOptional.get().getToken())                 .build();     } } <\/code><\/pre>\n<p>  <\/div>\n<\/p><\/div>\n<p>  \u0412 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 <b>required<\/b> \u0438 <b>notRequired<\/b> \u043c\u044b \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0448\u0443 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e. <br \/>  \u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d \u2014 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f json \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439, \u0430 \u0435\u0441\u043b\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d, \u0442\u043e \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435.<\/p>\n<p>  \u0412\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d, \u0442\u043e \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 <i>Hello guest!<\/i>, \u0430 \u0435\u0441\u043b\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d, \u0442\u043e \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f \u0435\u0433\u043e \u0438\u043c\u044f.<br \/>  \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u0432\u0441\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<p>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043e\u0431\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\/required<\/b>                         <\/p>\n<div class=\"spoiler_text\"><a href=\"https:\/\/habrastorage.org\/webt\/oi\/6n\/5b\/oi6n5btdtb3l13m6t_ktm50f3o4.png\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/oi\/6n\/5b\/oi6n5btdtb3l13m6t_ktm50f3o4.png\"\/><\/a>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\/not-required<\/b>                         <\/p>\n<div class=\"spoiler_text\"><a href=\"https:\/\/habrastorage.org\/webt\/2s\/3d\/vd\/2s3dvd764grmoh80deeau-bw33g.png\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/2s\/3d\/vd\/2s3dvd764grmoh80deeau-bw33g.png\"\/><\/a>  <\/div>\n<\/p><\/div>\n<p>  \u0412\u0441\u0435 \u043a\u0430\u043a \u0438 \u043e\u0436\u0438\u0434\u0430\u043b\u043e\u0441\u044c. \u0422\u0430\u043c \u0433\u0434\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u044b\u043b\u0430 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u2014 \u0432\u0435\u0440\u043d\u0443\u043b\u0430\u0441\u044c \u043e\u0448\u0438\u0431\u043a\u0430, \u0430 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u2014 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 <i>Hello guest!<\/i>.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c\u0441\u044f \u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0436\u0435 \u043c\u0435\u0442\u043e\u0434\u044b, \u043d\u043e \u0443\u0436\u0435 \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u0442\u043e\u043a\u0435\u043d\u0430 \u0432 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\/sign-up<\/b>                         <\/p>\n<div class=\"spoiler_text\"><a href=\"https:\/\/habrastorage.org\/webt\/tn\/2o\/qa\/tn2oqazthbl_iugmon4fy_fsxg4.png\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/tn\/2o\/qa\/tn2oqazthbl_iugmon4fy_fsxg4.png\"\/><\/a>  <\/div>\n<\/p><\/div>\n<p>  \u0412 \u043e\u0442\u0432\u0435\u0442\u0435 \u0432\u0435\u0440\u043d\u0443\u043b\u0441\u044f \u0442\u043e\u043a\u0435\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0442\u0435\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0433\u0434\u0435 \u043d\u0443\u0436\u043d\u0430 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f. <\/p>\n<p>  \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u044d\u0442\u043e:<\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\/required<\/b>                         <\/p>\n<div class=\"spoiler_text\"><a href=\"https:\/\/habrastorage.org\/webt\/zs\/xt\/ao\/zsxtaon0rutfyg4v0hids6gowui.png\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/zs\/xt\/ao\/zsxtaon0rutfyg4v0hids6gowui.png\"\/><\/a>  <\/div>\n<\/p><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\/not-required<\/b>                         <\/p>\n<div class=\"spoiler_text\"><a href=\"https:\/\/habrastorage.org\/webt\/ee\/wr\/ba\/eewrbavbjssfbzx5bgq0iytcsy0.png\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ee\/wr\/ba\/eewrbavbjssfbzx5bgq0iytcsy0.png\"\/><\/a>  <\/div>\n<\/p><\/div>\n<p>  \u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435. \u0412\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435.<\/p>\n<p>  <b>\u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442!<\/b><\/p>\n<h2><font color=\"#292e5b\">7. \u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/font><\/h2>\n<p>  \u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043d\u0435 \u043f\u0440\u0435\u0442\u0435\u043d\u0434\u0443\u0435\u0442 \u043d\u0430 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043a\u043e\u043c\u0443-\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e \u0434\u0443\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Spring Security. \u041d\u043e, \u043a\u0430\u043a \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435, \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d, \u0443\u0434\u043e\u0431\u0435\u043d \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0438 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/516638\/\"> https:\/\/habr.com\/ru\/post\/516638\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/516638\/\">\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f, \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u0443\u0434\u0430\u0447\u043d\u044b\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0435\u0433\u043e \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434\u0430 \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 REST API \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c JWT.<br \/>  \u042d\u0442\u043e \u043d\u0435 \u0437\u0430\u043c\u0435\u043d\u0430 Spring Security, \u043d\u043e \u044d\u0442\u043e\u0442 \u0441\u043f\u043e\u0441\u043e\u0431 \u0445\u043e\u0440\u043e\u0448\u043e \u0441\u0435\u0431\u044f \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u043e\u0442 \u0443\u0436\u0435 \u0431\u043e\u043b\u0435\u0435 \u0434\u0432\u0443\u0445 \u043b\u0435\u0442. <\/p>\n<p>  \u041f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043b\u044e\u0447\u0430 \u0434\u043b\u044f JWT \u0434\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u0436\u0435 \u043d\u0435\u0437\u043d\u0430\u043a\u043e\u043c\u043e\u043c\u0443 \u0441 JWT \u0441\u0442\u0430\u043b\u043e \u0432\u0441\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ic\/tu\/lc\/ictulc2gaazjvhlv3ojnzbot0by.png\"\/>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-309053","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/309053","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=309053"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/309053\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=309053"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=309053"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=309053"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}