{"id":268486,"date":"2015-11-18T19:15:06","date_gmt":"2015-11-18T16:15:06","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=268486"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=268486","title":{"rendered":"Google Cloud Endpoints \u043d\u0430 Java: \u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e. \u0447. 2 (Frontend)"},"content":{"rendered":"<p>       \u0427\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0432\u0430\u044f: <a href=\"http:\/\/habrahabr.ru\/post\/268863\/\">Google Cloud Endpoints \u043d\u0430 Java: \u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e. \u0447. 1<\/a><\/p>\n<p>  \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 <a href=\"https:\/\/cloud.google.com\/appengine\/docs\/java\/endpoints\/\">Google Cloud Endpoints \u0441 Java<\/a>, \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0435\u0447\u044c \u043f\u043e\u0439\u0434\u0435\u0442 \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u043a \u043d\u0430\u0448\u0435\u043c\u0443 API.<\/p>\n<p>  \u0412 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u043c\u0441\u044f \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f:<\/p>\n<p>  <a href=\"https:\/\/angularjs.org\/\">AngularJS<\/a>, \u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0431\u0449\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e <a href=\"http:\/\/getbootstrap.com\/\">Bootstrap<\/a> \u0438\u043b\u0438 <a href=\"http:\/\/foundation.zurb.com\/\">Foundation<\/a>.<\/p>\n<p>  \u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f \u0434\u0435\u043f\u043b\u043e\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>  <a name=\"habracut\"><\/a><\/p>\n<h1>\u041b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440<\/h1>\n<p>  \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 AngularJS \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430 \u00ab\u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445\u00bb \u0444\u0430\u0439\u043b\u043e\u0432: .html, .js, .css + \u0444\u0430\u0439\u043b\u044b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u0448\u0440\u0438\u0444\u0442\u044b \u0438 \u0442.\u043f. \u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c index.html \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c index.html \u0432 Google Chrome \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0431\u0435\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u0438 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u043d\u0435\u0447\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u044d\u0442\u043e\u0433\u043e:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/206\/63b\/3d0\/20663b3d045db2775269310fdeabf905.png\" alt=\"image\"\/><\/p>\n<p>  \u0412 Firefox \u0442\u043e \u0436\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0431\u0435\u0437 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u043e \u0441\u0441\u044b\u043b\u043a\u0438 \u0432\u0438\u0434\u0430 src=&quot;\/\/\u2026 \u0438\u043b\u0438 href=&quot;\u2026 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044e\u0442\u0441\u044f \u0432 file:\/\/\/\u2026<br \/>  \u041d\u0443 \u0438 <a href=\"https:\/\/developers.google.com\/web\/tools\/chrome-devtools\/\">Chrome DevTools<\/a>, \u043a\u0430\u043a \u043c\u043e\u0439 \u0432\u043a\u0443\u0441 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435.<\/p>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0435 \u0436\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u0435\u0435. \u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"http:\/\/www.sinatrarb.com\/\">Sinatra<\/a> \u043d\u0430 Ruby, <a href=\"https:\/\/nodejs.org\">NodeJS<\/a>, \u0441\u0442\u0430\u0440\u044b\u0439 \u0434\u043e\u0431\u0440\u044b\u0439 <a href=\"https:\/\/httpd.apache.org\/\">Apache HTTP Server (\u00abhttpd\u00bb)<\/a>. App Engine Java SDK \u0442\u0430\u043a\u0436\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 development web server \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c\u044b\u0439 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435, \u0438 \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u0430 GAE \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0431\u0430\u0437\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 (datastore).<br \/>  \u0412 IntelliJ IDEA \u043f\u0440\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 .html \u0444\u0430\u0439\u043b\u0430 \u0432\u044b\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0438\u043a\u043e\u043d\u043a\u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432, \u0435\u0441\u043b\u0438 \u043a\u043b\u0438\u043a\u043d\u0443\u0442\u044c \u0442\u043e \u0444\u0430\u0439\u043b \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u043c IntelliJ IDEA.<\/p>\n<p>  \u041d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0441\u0430\u043c\u044b\u043c \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0438 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f Python (\u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u0447\u0442\u043e \u043e\u043d \u0443 \u0412\u0430\u0441 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d):  <\/p>\n<pre><code class=\"bash\">python -m SimpleHTTPServer &lt;port&gt; <\/code><\/pre>\n<p>  \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u00abpython\u00bb \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a Python \u0432\u0435\u0440\u0441\u0438\u0438 2.x (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e), &quot;-m&quot; \u2014 \u0437\u0430\u043f\u0443\u0441\u043a <a href=\"https:\/\/docs.python.org\/2\/using\/cmdline.html#cmdoption-m\">\u043c\u043e\u0434\u0443\u043b\u044f<\/a>, &quot;<a href=\"https:\/\/docs.python.org\/2\/library\/simplehttpserver.html\">SimpleHTTPServer<\/a>&quot; \u2014 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u043e\u0434\u0443\u043b\u044c \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 http-\u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 (\u0442.\u0435. \u0435\u0441\u043b\u0438 \u0443 \u0412\u0430\u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d Python, \u0442\u043e \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u0443\u0436\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442), \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e  \u2014 \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u0440\u0442\u0430, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c, \u0442\u043e \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0431\u0443\u0434\u0435\u0442 8000.<br \/>  <i>\u042d\u0442\u0443 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u043d\u0430\u0434\u043e \u0438\u0441\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0442\u0430\u043c \u0433\u0434\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430\u0448 index.htm<\/i>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432 \/ \u043d\u0430 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0438 \u043d\u0430 <a href=\"http:\/\/localhost\">localhost<\/a>:8000\/ (http:\/\/127.0.0.1:8000\/) \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 http-\u0441\u0435\u0440\u0432\u0435\u0440. \u0423\u0434\u043e\u0431\u043d\u043e \u0442\u0435\u043c \u0447\u0442\u043e \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0432 \u0441\u0430\u043c\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438, \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043d\u0435 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<h1>\u0414\u0435\u043f\u043b\u043e\u0439<\/h1>\n<p>  \u0420\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0444\u0440\u043e\u043d\u0442-\u044d\u043d\u0434 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e API \u043c\u043e\u0436\u043d\u043e \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u043c <a href=\"https:\/\/pages.github.com\/\">GitHub Pages<\/a> (\u0441\u043c. \u0442\u0430\u043a\u0436\u0435 <a href=\"https:\/\/help.github.com\/articles\/setting-up-a-custom-domain-with-github-pages\/\">Setting up a custom domain with GitHub Pages<\/a>) \u0438\u043b\u0438 \u043d\u0430 <a href=\"http:\/\/aws.amazon.com\">Amazon Web Services (AWS)<\/a>.<\/p>\n<p>  \u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u043d\u0430 GAE. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432 \u043e\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u0412 \u043d\u0430\u0448\u0435\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435, \u0432 \u0443\u0447\u0435\u0431\u043d\u044b\u0445 \u0446\u0435\u043b\u044f\u0445, \u043c\u044b \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u0431\u044d\u043a\u0435\u043d\u0434 \u0438 \u0444\u0440\u043e\u043d\u0442-\u044d\u043d\u0434 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043d\u0430 GAE. \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u0432\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430. \u0424\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u0431\u0443\u0434\u0435\u0442 \u0436\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0432 hello-habrahabr-webapp, \u0430 \u0431\u044d\u043a\u0435\u043d\u0434 \u0432 hello-habrahabr-api.<\/p>\n<h2>\u0414\u043e\u043c\u0435\u043d<\/h2>\n<p>  \u0412 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u0438\u043c\u0435\u044e\u0449\u0435\u043c\u0443\u0441\u044f \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u043c\u0443 \u0438\u043c\u0435\u043d\u0438 \u0432\u0438\u0434\u0430 {\u043f\u0440\u043e\u0435\u043a\u0442 ID}.appspot.com, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0434\u043e\u043c\u0435\u043d \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u0430\u043a \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/domains.google.com\">Google Domains<\/a>, \u0442\u0430\u043a \u0438 \u0443 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430, \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043c\u0435\u043d\u043e\u0432 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0420\u0430\u043d\u0435\u0435 \u044d\u0442\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0434\u043e\u043c\u0435\u043d\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0432 <a href=\"https:\/\/www.google.com\/work\/apps\/business\/\">Google Apps<\/a>, \u043d\u043e \u0441 \u043d\u0435\u0434\u0430\u0432\u043d\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 \u043a Google Apps \u0443\u0431\u0440\u0430\u043d\u0430.<\/p>\n<p>  \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043c\u0435\u043d, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u043c\u0435\u043d\u044e: Compute -&gt; App Engine -&gt; Settings -&gt; Custom domains. \u0417\u0430\u0442\u0435\u043c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c &#8216;Register a new domain&#8217; \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043c\u0435\u043d \u0443 Google, \u0438\u043b\u0438 \u0435\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0434\u043e\u043c\u0435\u043d &#8216;Add a custom domain&#8217;<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/47c\/e33\/137\/47ce331373a15969d4d6d8e6a5d4dc17.png\" alt=\"image\"\/><\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u043e\u043c\u0435\u043d \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0435 \u0443 Google, \u0442\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0447\u0442\u043e \u0432\u044b \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0438\u043a \u0434\u043e\u043c\u0435\u043d\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043c\u0435\u043d \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u043d\u043d\u044b\u0445 \u043d\u0430 \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0439 \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 google: \u0432\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0434\u043e\u043c\u0435\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u0432 \u043f\u043e\u043b\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0435 \u0446\u0438\u0444\u0440\u043e\u0439 1, \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c &#8216;Verify&#8217; \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/33c\/f66\/a95\/33cf66a95e68bd2df09a3c1105cfb643.png\" alt=\"image\"\/><\/p>\n<p>  \u0435\u0441\u043b\u0438 \u0434\u043e\u043c\u0435\u043d \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0443 godaddy.com \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043a\u0440\u0443\u043f\u043d\u043e\u0433\u043e \u0434\u043e \u0434\u043b\u044f \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u0438 \u0438 \u043e\u0442\u043a\u0440\u044b\u0432\u0448\u0435\u043c\u0441\u044f \u043e\u043a\u043d\u0435 \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0438\u0442\u044c\u0441\u044f:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/ee3\/a4f\/d26\/ee3a4fd26fc360f31e9b2c3bb1df9384.png\" alt=\"image\"\/><\/p>\n<p>  \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/aa2\/e15\/9c0\/aa2e159c0c765f84567ef96ee8d7d4d8.png\" alt=\"image\"\/><\/p>\n<p>  \u041b\u0438\u0431\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u044b \u043f\u043e \u043a\u043b\u0438\u043a\u0443 \u043d\u0430 &#8216;Add a TXT record.&#8217;<\/p>\n<p>  \u041d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/2a4\/4dd\/7db\/2a44dd7db41656da2f251855470fc50d.png\" alt=\"image\"\/><\/p>\n<p>  \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u00ab\u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u00bb \u0432\u0435\u0440\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u043c\u0435\u043d\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c google \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u043e\u043c\u0435\u043d\u043e\u043c \u0432 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u0445 Google.<\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0432\u0435\u0440\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u043e\u043c\u0435\u043d\u0430, \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u043c \u0446\u0438\u0444\u0440\u043e\u0439 2. (\u0435\u0441\u043b\u0438 \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u0434\u043e\u043c\u0435\u043d, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0447\u0442\u043e\u0431\u044b \u043d\u043e\u0432\u044b\u0439 \u0434\u043e\u043c\u0435\u043d \u0441\u0442\u0430\u043b \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430) \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0434\u043e\u043c\u0435\u043d \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443, \u043b\u0438\u0431\u043e \u00ab\u0446\u0435\u043b\u0438\u043a\u043e\u043c\u00bb, \u043b\u0438\u0431\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0441\u0443\u0431\u0434\u043e\u043c\u0435\u043d, \u043b\u0438\u0431\u043e \u0438 \u0442\u043e \u0438 \u0434\u0440\u0443\u0433\u043e\u0435.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/9bd\/e56\/7e0\/9bde567e063da9be5038e783bab4fe19.png\" alt=\"image\"\/><\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u0434\u043e\u043c\u0435\u043d\u0430 \u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438 &#8216;Add&#8217;, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432\u043d\u0435\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043e\u043c\u0435\u043d\u0430 \u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430 (DNS Zone File) \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u043e\u0434 \u0446\u0438\u0444\u0440\u043e\u0439 3:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/419\/a64\/3a8\/419a643a86bbd82256eeb7149e041405.png\" alt=\"image\"\/><\/p>\n<p>  \u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u043f\u043e\u0441\u043b\u0435 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438 &#8216;Add&#8217; \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f, \u043d\u0430\u0434\u043e \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0440\u0430\u0437\u0434\u0435\u043b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#8216;Application settings&#8217;), \u0438 \u0441\u043d\u043e\u0432\u0430 \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u0432 &#8216;Custom domains&#8217; \u2014 \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u0430\u043c \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u044b \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 (\u0441\u0443\u0431)\u0434\u043e\u043c\u0435\u043d\u044b \u0438 \u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0431\u0443\u0434\u0435\u0442 (\u043d\u0435 \u0441\u0440\u0430\u0437\u0443, \u0430 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0434\u043e 24 \u0447\u0430\u0441\u043e\u0432) \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043a\u0430\u043a \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 {\u043f\u0440\u043e\u0435\u043a\u0442 ID}.appspot.com, \u0442\u0430\u043a \u0438 \u043f\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0430\u0434\u0440\u0435\u0441\u0430\u043c (\u0434\u043e\u043c\u0435\u043d\u0430\u043c).<\/p>\n<h1>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 SSL<\/h1>\n<p>  \u0414\u043e\u0441\u0442\u0443\u043f \u043a \u0430\u0434\u0440\u0435\u0441\u0443 {\u043f\u0440\u043e\u0435\u043a\u0442 ID}.appspot.com \u043c\u043e\u0436\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u043f\u043e http \u0442\u0430\u043a \u0438 https<br \/>  \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043f\u043e https \u043a \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c\u0443 \u0434\u043e\u043c\u0435\u043d\u0443, \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f SSL-\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0438\u0439 \u0446\u0435\u043d\u0442\u0440\u043e\u043c (\u0430\u043d\u0433\u043b. Certification authority, CA) \u043f\u043e\u0434\u043f\u0438\u0441\u044c \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u043c\u0438.<br \/>  \u0412\u0435\u0434\u0443\u0449\u0438\u043c\u0438 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Certificate_authority#Providers\">\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430\u043c\u0438<\/a> \u0443\u0441\u043b\u0443\u0433 \u0443\u0434\u043e\u0441\u0442\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0435\u0433\u043e \u0446\u0435\u043d\u0442\u0440\u0430 \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f <a href=\"http:\/\/www.symantec.com\">Symantec<\/a> \u0441 \u0431\u0440\u0435\u043d\u0434\u0430\u043c\u0438 <a href=\"https:\/\/www.geotrust.com\">GeoTrust<\/a>, <a href=\"https:\/\/www.thawte.com\/\">Thawte<\/a>, <a href=\"https:\/\/www.symantec.com\/ssl-certificates\/\">Verisign<\/a>, \u0442\u043e\u0442 \u0436\u0435 <a href=\"https:\/\/www.godaddy.com\/web-security\/ssl-certificate\">Godaddy<\/a>, \u0438 <a href=\"https:\/\/www.comodo.com\/\">Comodo<\/a>. \u041d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0434\u043e\u043b\u044f \u0440\u044b\u043d\u043a\u0430, \u0438 \u0431\u043e\u043b\u0435\u0435 \u043d\u0438\u0437\u043a\u0438\u0435 \u0446\u0435\u043d\u044b \u0443 Comodo. \u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b \u0447\u0435\u0440\u0435\u0437 \u0440\u0435\u0441\u0435\u043b\u043b\u0435\u0440\u043e\u0432 \u0446\u0435\u043d\u0430 \u043e\u0431\u044b\u0447\u043d\u043e \u0435\u0449\u0435 \u043d\u0438\u0436\u0435.<br \/>  \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430\/\u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/www.comodo.com\/e-commerce\/ssl-certificates\/free-ssl-certificate.php\">\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u043c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u043c \u043e\u0442 Comodo \u043d\u0430 90 \u0434\u043d\u0435\u0439<\/a> (\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u0432\u044b\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u043d\u0430 \u0434\u043e\u043c\u0435\u043d) \u0438\/\u0438\u043b\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043d\u0430 30 \u0434\u043d\u0435\u0439 \u043e\u0442 <a href=\"https:\/\/www.freessl.com\/\">RapidSSL<\/a>.<\/p>\n<p>  \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0443 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Certificate_signing_request\">certificate signing request (CSR)<\/a> (\u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u0434\u043f\u0438\u0441\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430). \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435, \u043e\u0434\u043d\u0430\u043a\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0442 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438 \u0447\u0442\u043e \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u0431\u0443\u0434\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0443 \u0432\u0430\u0441, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 CSR \u043b\u0443\u0447\u0448\u0435 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439 <a href=\"https:\/\/www.openssl.org\/\">OpenSSL<\/a>.<\/p>\n<p>  \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u0430\u0439\u043b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f CSR ( \u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e scr.conf ):  <\/p>\n<pre><code class=\"bash\"># csr.conf # you can rename scr.conf, scr.key, scr.csr to filenames you prefer, # but with the same filename extensions [req] default_bits       = 2048 # default_md         = sha512 default_keyfile    = csr.key #name of keyfile distinguished_name = req_distinguished_name prompt             = yes # If 'prompt = no' provide right values to properties, not to _default properties # and remove or comment _default properties. # Use 'yes' and _default to see and correct values interactively encrypt_key        = no # # req_extensions = v3_req           #this is for multi-domain certificate  [req_distinguished_name] # # Use your company name, e-mai, domain names as default values # if you enter '.', the field will be left blank # countryName = Country Name (2 letter code) countryName_default = GB stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = City of London localityName = Locality Name (eg, city) localityName_default = London organizationName = Organization name organizationName_default = MyCompany Limited organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = . commonName = This is fully qualified domain name that you wish to secure # e.g. www.example.com or mail.example.com commonName_default = www.my-domain.com emailAddress = Email Address emailAddress_default = admin@my-domain.com  # [v3_req] # subjectAltName = @alt_names       #this is for multi-domain certificate  # [alt_names]                       #this is for multi-domain certificate # DNS.1   = my-domain.net           #this is for multi-domain certificate # DNS.2   = my-domain.org           #this is for multi-domain certificate # DNS.3   = myseconddomain.com      #this is for multi-domain certificate  # to generate .csr: # openssl req -newkey rsa:2048 -sha512 -out csr.csr -config csr.conf # or: # openssl req -newkey rsa:2048 -sha512 -nodes -out csr.csr -config csr.conf # Note:  If the &quot;-nodes&quot; is entered the key will NOT be encrypted with a # DES pass phrase, ( see: # https:\/\/support.comodo.com\/index.php?\/Default\/Knowledgebase\/Article\/View\/1\/19\/csr-generation-using-openssl-apache-wmod_ssl-nginx-os-x # ) # # to verify .csr: # openssl req -text -noout -verify -in csr.csr # # in one command generate and verify: # openssl req -newkey rsa:2048 -out csr.csr -config csr.conf && openssl req -text -noout -verify -in csr.csr #  <\/code><\/pre>\n<p>  \u0442\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code class=\"bash\">openssl req -newkey rsa:2048 -out csr.csr -config csr.conf <\/code><\/pre>\n<p>  \u0435\u0441\u043b\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u043c\u044b \u0443\u043a\u0430\u0437\u0430\u043b\u0438 &#8216;prompt = yes&#8217;, \u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0432\u043e\u0434\u0438\u043c\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0438\u0445. \u0415\u0441\u043b\u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0436\u043c\u0435\u043c &#8216;Enter&#8217;<\/p>\n<p>  \u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u0444\u0430\u0439\u043b\u0430: csr.key \u2014 \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u043a\u043b\u044e\u0447, \u0438 csr.csr \u2014 \u044d\u0442\u043e CSR (\u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043f\u043e\u0434\u043f\u0438\u0441\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430)<\/p>\n<p>  \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c CSR \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439:  <\/p>\n<pre><code class=\"bash\">openssl req -text -noout -verify -in csr.csr <\/code><\/pre>\n<p>  \u0424\u0430\u0439\u043b .csr \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u043e\u043c, \u0432\u043d\u0443\u0442\u0440\u0438 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u0447\u0442\u043e \u0432\u0440\u043e\u0434\u0435:  <\/p>\n<pre><code class=\"bash\">-----BEGIN CERTIFICATE REQUEST----- MIIC5TCCAc0CAQAwgZ8xCzAJBgNVBAYTAkdCMRcwFQYDVQQIDA5DaXR5IG9mIExv bmRvbjEPMA0GA1UEBwwGTG9uZG9uMRowGAYDVQQKDBFNeUNvbXBhbnkgTGltaXRl NZBB4bDdgJ+uyNZq54dM1tUvzSolv\/+LAY78\/z85edqLH4nc5CxgMEn8hurFOpB4 RXS+ShhpBsJr6RJhSk2xkRe\/idkM\/TUon\/7n1TUthFpjv2tYQZ6on3iWUZ61FDuM mNPHGMIX+sn\/OceViRtlu1Lx+t4JV9dTJQ== -----END CERTIFICATE REQUEST----- <\/code><\/pre>\n<p>  \u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0438 \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u0444\u043e\u0440\u043c\u0443 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435, \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u0443\u044e:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/e6e\/55d\/21a\/e6e55d21a69523430a4173af6244adea.png\" alt=\"image\"\/><\/p>\n<p>  \u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u044f \u0434\u043e\u043c\u0435\u043d\u043e\u043c \u0443 \u0432\u0430\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a e-mail \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0434\u0430\u0435\u0442 whois, \u043b\u0438\u0431\u043e \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u0438\u0437 email \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0434\u043e\u043c\u0435\u043d\u0435:<br \/>  admin@<br \/>  administrator@<br \/>  postmaster@<br \/>  hostmaster@<br \/>  webmaster@<\/p>\n<p>  \u041b\u0438\u0431\u043e \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c http: \/\/yourdomain.com\/{Upper case value of MD5 hash of CSR}.txt \u0438\u043b\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c DNS CNAME record \u0443\u043a\u0430\u0437\u0430\u0432 \u043e\u043f\u044f\u0442\u044c \u0436\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0445\u044d\u0448.<\/p>\n<p>  \u0420\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430: Extended Business Verification \u0438\u043b\u0438 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u043d\u043e EV, \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442, \u043d\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u0441 \u00ab\u0437\u0435\u043b\u0435\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439\u00bb (GreenBar) \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0438\u043c\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u2014 \u0432\u043b\u0430\u0434\u0435\u043b\u044c\u0446\u0430 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430.<\/p>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441 \u0441\u0430\u0439\u0442\u0430 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430 \u0438\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u0435 \u0444\u0430\u0439\u043b \u0432\u0438\u0434\u0430 {\u0432\u0430\u0448 domain \u0438\u043b\u0438 \u043d\u043e\u043c\u0435\u0440 \u0437\u0430\u043a\u0430\u0437\u0430}.crt, \u043e\u0431\u044b\u0447\u043d\u043e \u0432 \u043f\u0430\u043a\u0435\u0442\u0435 (.zip) \u0441 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430\u043c\u0438 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0446\u0435\u043d\u0442\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u044e\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 .crt \u042d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b .zip \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u0430\u0440\u0445\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e.<\/p>\n<p>  \u041d\u0430\u0448 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0438 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0443\u044e\u0441\u044f \u0432 \u043d\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439:  <\/p>\n<pre><code class=\"bash\">openssl x509 -in {\u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430}.crt -text -noout <\/code><\/pre>\n<p>  \u0433\u0434\u0435 {\u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430}.crt \u2014 \u0438\u043c\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043b\u044f GAE \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 \u0438\u0437 \u0444\u043e\u0440\u043c\u0430\u0442\u0430 .key \u0432 \u0444\u043e\u0440\u043c\u0430\u0442 .pem:  <\/p>\n<pre><code class=\"bash\">openssl rsa -in *.key &gt; forGAE.key.pem <\/code><\/pre>\n<p>  <b><i>\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/i><\/b>: \u0432 \u044d\u0442\u043e\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 -text, \u043a\u0430\u043a \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e\u0442 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 Google, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 \u043a\u043b\u044e\u0447 \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0439 \u0438 \u043b\u0438\u0448\u043d\u0438\u0439 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u0435\u043a\u0441\u0442. \u0415\u0441\u043b\u0438 \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a\u043b\u044e\u0447, \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435:<br \/>  &#8216;The private key you&#8217;ve selected does not appear to be valid&#8217;<br \/>  \u0442\u043e \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430 \u0432 \u044d\u0442\u043e\u043c. \u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u0444\u0430\u0439\u043b \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u043e\u043c \u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u0435 \u0432\u0441\u0435 \u0447\u0442\u043e \u0432\u044b\u0448\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 &#8212;&#8212;BEGIN RSA PRIVATE KEY&#8212;&#8212;<br \/>  \u0418\u043b\u0438 \u043f\u0435\u0440\u0435\u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u043a\u043b\u044e\u0447 \u0435\u0449\u0435 \u0440\u0430\u0437, \u0431\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 -text<\/p>\n<p>  2) \u0441\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u044c (\u0441oncatenate) \u0432\u0441\u0435 .crt \u0444\u0430\u0439\u043b\u044b \u0438\u0437 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e .zip \u0444\u0430\u0439\u043b\u0430 (\u0438 \u043d\u0430\u0448 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442, \u0438 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0430), \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0430:<br \/>  <code> cat mydomain_com.crt ASecureServerCA.crt ATrustCA.crt ATrustExternal.crt &gt; concat.crt <\/code><\/p>\n<p>  <b><i>\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435<\/i><\/b>: <i>\u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0432\u0430\u0436\u0435\u043d<\/i>, (\u043f\u0440\u043e\u0441\u0442\u043e cat *.crt &gt; concat.crt \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435 \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442) \u043f\u0435\u0440\u0432\u044b\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u0434\u0442\u0438 \u043d\u0430\u0448 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u0434\u043e\u043c\u0435\u043d\u0430, \u043f\u043e\u0442\u043e\u043c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0446\u0435\u043d\u0442\u0440\u0430 \u0438\u043c\u0435\u043d\u0430 \u0444\u0430\u043b\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f, \u043d\u043e \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0445\u043e\u0436\u0438\u043c\u0438 \u043d\u0435 \u0442\u0435 \u0447\u0442\u043e \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b:<\/p>\n<pre><code class=\"bash\">openssl x509 -noout -modulus -in concat.crt | openssl md5 <\/code><\/pre>\n<p>  \u0438  <\/p>\n<pre><code class=\"bash\">openssl rsa -noout -modulus -in forGAE.key.pem | openssl md5 <\/code><\/pre>\n<p>  \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u043c\u0435\u043d\u044e \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c Compute -&gt; Settings -&gt; SSL Sertificates -&gt; Upload a new certificate<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/008\/4c6\/96c\/0084c696cdf9c12566a1f7760da60af4.png\" alt=\"image\"\/><\/p>\n<p>  \u0412 \u043f\u043e\u043b\u0435 &#8216;Name&#8217; \u0432\u0432\u043e\u0434\u0438\u043c \u0438\u043c\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0445\u043e\u0442\u0438\u043c \u0434\u0430\u0442\u044c \u043d\u0430\u0448\u0435\u043c\u0443 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0443 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430.<br \/>  \u0412 &#8216;PEM encoded X.509 public key certificate&#8217; \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043d\u0430\u0448 concat.crt<br \/>  \u0412 \u043f\u043e\u043b\u0435 &#8216;Unencrypted PEM encoded RSA private key&#8217; \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043d\u0430\u0448 \u043a\u043b\u044e\u0447 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 .pem (forGAE.key.pem)<br \/>  \u0416\u043c\u0435\u043c &#8216;Upload&#8217;<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/64d\/ceb\/411\/64dceb411f58ce711b1a5b5161e051f3.png\" alt=\"image\"\/><\/p>\n<p>  \u041e\u0442\u043c\u0435\u0447\u0430\u0435\u043c \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u044b \u043d\u0430\u043f\u0440\u043e\u0442\u0438\u0432 \u0434\u043e\u043c\u0435\u043d\u043d\u044b\u0445 \u0438\u043c\u0435\u043d \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c (\u0438 \u0445\u043e\u0442\u0438\u043c) \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 (\u044d\u0442\u043e \u0442\u0435 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b \u0432 \u0441\u0430\u043c\u043e\u043c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0435, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e), \u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u0441\u0438\u043d\u044e\u044e \u043a\u043d\u043e\u043f\u043a\u0443 &#8216;Save&#8217;:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/0e7\/abc\/c5a\/0e7abcc5a9744969e9b91f9394819b15.png\" alt=\"image\"\/><\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u0430\u0434\u0440\u0435\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u043d\u0430\u0431\u0435\u0440\u0435\u043c \u0438\u043c\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0434\u043e\u043c\u0435\u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u0432 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b httpS:\/\/<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/5b8\/b63\/aa2\/5b8b63aa2c39c22bcd9354c3c349512a.png\" alt=\"image\"\/><\/p>\n<p>  \u041d\u0430 \u0441\u0430\u0439\u0442\u0435 \u043f\u043e\u043a\u0430 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435\u0442, \u043d\u043e \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0430\u0434\u0440\u0435\u0441\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0437\u0435\u043b\u0435\u043d\u044b\u0439 \u0437\u0430\u043c\u043e\u0447\u0435\u043a, \u043a\u043b\u0438\u043a\u043d\u0443\u0432 \u043f\u043e \u043d\u0435\u043c\u0443 \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u0430.<br \/>  SSL \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442.<\/p>\n<h1> \u0421\u043a\u0435\u043b\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f <\/h1>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u043a\u0430\u043a \u0432 <a href=\"http:\/\/habrahabr.ru\/post\/268863\/\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c Maven:  <\/p>\n<pre><code class=\"bash\">mvn archetype:generate -Dappengine-version=1.9.28 -Dapplication-id=hello-habrahabr-webapp -Dfilter=com.google.appengine.archetypes: <\/code><\/pre>\n<p>  (hello-habrahabr-webapp \u2014 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0442 ID)<\/p>\n<p>  \u041d\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 Cloud Points API, \u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u0430\u0440\u0445\u0435\u0442\u0438\u043f\u0430 \u21162, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0430\u0440\u0445\u0435\u0442\u0438\u043f \u21161 (\u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u043a\u0435\u043b\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 GAE):  <\/p>\n<pre><code class=\"bash\">1: remote -&gt; com.google.appengine.archetypes:appengine-skeleton-archetype (A skeleton application with Google App Engine) <\/code><\/pre>\n<p>  \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u2014 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u0437\u043b\u043e\u0436\u0435\u043d\u043e \u0432 <a href=\"http:\/\/habrahabr.ru\/post\/268863\/\">\u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/a>, \u043d\u043e \u0441 \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u0440\u043e\u0435\u043a\u0442 ID.<br \/>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c Maven \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u043d\u0430\u043c \u043f\u0430\u043f\u043a\u0443 hello-habrahabr-webapp, \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u0444\u0430\u0439\u043b\u043e\u0432 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0439 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443, \u043d\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f src\/main\/java\/ \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0441\u0442\u0430, \u0438 \u0434\u043b\u044f \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u043e\u043d\u0430 \u043d\u0430\u043c \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f.<\/p>\n<p>  \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u043a\u0430\u043a \u043c\u044b \u0434\u0435\u043b\u0430\u043b\u0438 \u0440\u0430\u043d\u044c\u0448\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c pom.xml (\u0432 &lt;appengine.version&gt;1.9.27&lt;\/appengine.version&gt; \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e 1.2.8). \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e src\/main\/webapp\/WEB-INF\/ \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0444\u0430\u0439\u043b\u044b appengine-web.xml \u0438 web.xml<br \/>  web.xml \u043d\u0430\u0441 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0447\u0442\u0438 \u043f\u0443\u0441\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043d\u0435\u0433\u043e (\u043c\u0435\u0436\u0434\u0443 &lt;web-app&gt; &lt;\/web-app&gt;) \u0440\u0430\u0437\u0434\u0435\u043b\u044b security-constraint \u0438 welcome-file-list:  <\/p>\n<pre><code class=\"xml\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt; &lt;web-app version=&quot;2.5&quot; xmlns=&quot;http:\/\/java.sun.com\/xml\/ns\/javaee&quot; xmlns:xsi=&quot;http:\/\/www.w3.org\/2001\/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http:\/\/java.sun.com\/xml\/ns\/javaee http:\/\/java.sun.com\/xml\/ns\/javaee\/web-app_2_5.xsd&quot;&gt;     &lt;!-- Force SSL for entire site --&gt;     &lt;!-- (server automatically redirects the requests to the SSL port         if you try to use HTTP ) --&gt;     &lt;security-constraint&gt;         &lt;web-resource-collection&gt;             &lt;web-resource-name&gt;Entire Application&lt;\/web-resource-name&gt;             &lt;url-pattern&gt;\/*&lt;\/url-pattern&gt;         &lt;\/web-resource-collection&gt;         &lt;user-data-constraint&gt;             &lt;transport-guarantee&gt;CONFIDENTIAL&lt;\/transport-guarantee&gt;         &lt;\/user-data-constraint&gt;     &lt;\/security-constraint&gt;     &lt;!-- Welcome file list --&gt;     &lt;welcome-file-list&gt;         &lt;welcome-file&gt;index.html&lt;\/welcome-file&gt;     &lt;\/welcome-file-list&gt;     &lt;!--  --&gt; &lt;\/web-app&gt; <\/code><\/pre>\n<p>  \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b set.account.sh \u0438 commit.push.build.and.upload.sh \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0435 \u0442\u0435\u043c \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u044b\u043b\u0438 \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u044b:  <\/p>\n<pre><code class=\"bash\">git init gcloud init git config credential.helper gcloud.sh git remote add google https:\/\/source.developers.google.com\/p\/hello-habrahabr-webapp git push --all google set.account.sh commit.push.build.and.upload.sh <\/code><\/pre>\n<p>  \u0423\u0431\u0435\u0436\u0434\u0430\u0435\u043c\u0441\u044f \u0447\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440.<br \/>  Maven \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 .war \u0444\u0430\u0439\u043b \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u0439\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 target, \u0438 \u0432\u044b\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0435\u0433\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 GAE. \u042d\u0442\u043e\u0442 \u0436\u0435 \u0444\u0430\u0439\u043b \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043f\u043b\u043e\u0438\u0442\u044c \u0438 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b\u0439 java-\u0441\u0435\u0440\u0432\u0435\u0440 (Tomcat, Jetty)<\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043f\u0440\u0438 \u043f\u043e\u043f\u044b\u0442\u043a\u0435 \u0437\u0430\u0439\u0442\u0438 \u043d\u0430 \u0441\u0430\u0439\u0442 \u043f\u043e \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0443 http:\/\/ \u0441\u0435\u0440\u0432\u0435\u0440 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430 https:\/\/<\/p>\n<h1> \u0414\u043e\u0441\u0442\u0443\u043f \u043a API \u0431\u0435\u0437 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/h1>\n<p>  \u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e. \u0412 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 API \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0431\u0435\u0437 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 (&#8216;myApi API&#8217;) \u043f\u043e POST \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u043d\u0430 \u0430\u0434\u0440\u0435\u0441 <a href=\"https:\/\/hello-habrahabr-api.appspot.com\/_ah\/api\/myApi\/v1\/register\">hello-habrahabr-api.appspot.com\/_ah\/api\/myApi\/v1\/register<\/a> ( \u0444\u0430\u0439\u043b YourFirstAPI.java ). \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0432\u044b\u0434\u0430\u0432\u0430\u043b \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432 logs, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u044e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0432 \u043c\u0435\u043d\u044e \u043f\u0440\u043e\u0435\u043a\u0442\u0430: Monitoring -&gt; Logs, \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043b \u0442\u0430\u043a\u0436\u0435 \u043c\u0435\u0442\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0439 GET \u0437\u0430\u043f\u0440\u043e\u0441:  <\/p>\n<pre><code class=\"java\">package com.appspot.hello_habrahabr_api;  import com.google.api.server.spi.config.Api; import com.google.api.server.spi.config.ApiMethod; import com.google.api.server.spi.config.ApiMethod.HttpMethod; import java.util.logging.Logger; import java.util.Random;  @Api(name = &quot;myApi&quot;, \/\/The api name must match '[a-z]+[A-Za-z0-9]*'      version = &quot;v1&quot;,      scopes = {Constants.EMAIL_SCOPE},      description = &quot;first API for this application.&quot;) public class YourFirstAPI {    @SuppressWarnings(&quot;unused&quot;)   private static final Logger LOG = Logger.getLogger(YourFirstAPI.class.getName());    @ApiMethod(              name = &quot;registerPOST&quot;,              path = &quot;register&quot;,              httpMethod = HttpMethod.POST              )   @SuppressWarnings(&quot;unused&quot;)   public MessageToUser registerPOST(final UserForm userForm) {      LOG.warning(&quot;[YourFirstAPI] (HTTP Method: POST): userForm: {name: &quot; + userForm.getName() + &quot;, age: &quot; + userForm.getAge() + &quot;, ishuman: &quot; + userForm.getIshuman() + &quot;}&quot; );      MessageToUser messageToUser = new MessageToUser();     messageToUser.setMessage(&quot;Hi, &quot; + userForm.getName() + &quot;, you are registered on our site&quot;);     Random random = new Random();     messageToUser.setUsernumber(random.nextInt(100) + 1);     messageToUser.setIsregistered(true);     return messageToUser;}    @ApiMethod(              name = &quot;getGreeting&quot;,              path = &quot;getgreeting&quot;,              httpMethod = HttpMethod.GET              )   @SuppressWarnings(&quot;unused&quot;)   public MessageToUser getGreeting(final UserForm userForm) {      LOG.warning(&quot;[YourFirstAPI] (HTTP Method: GET): userForm: {name: &quot; + userForm.getName() + &quot;, age: &quot; + userForm.getAge() + &quot;, ishuman: &quot; + userForm.getIshuman() + &quot;}&quot; );      MessageToUser messageToUser = new MessageToUser();      messageToUser.setMessage(&quot;Hi, &quot; + userForm.getName() + &quot;, nice to meet you :)&quot;);     Random random = new Random();     messageToUser.setUsernumber(random.nextInt(100) + 1);     messageToUser.setIsregistered(false);     return messageToUser;} } <\/code><\/pre>\n<p>  \u0438 \u0437\u0430\u0434\u0435\u043f\u043b\u043e\u0438\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 (\u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u0440\u0430\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u043c commit.push.build.and.upload.sh )<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0444\u043e\u0440\u043c\u0443 \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e src\/main\/webapp\/ \u2014 \u044d\u0442\u043e \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 index.html, \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438, \u043a\u0440\u043e\u043c\u0435 WEB-INF\/ \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 Java-\u0441\u0435\u0440\u0432\u0435\u0440 \u0442\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u043b\u044e\u0431\u043e\u0439 \u0442\u0430\u043a\u043e\u0439 \u0444\u0430\u0439\u043b \u043c\u043e\u0436\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0435\u0440\u0432\u043b\u0435\u0442\u043e\u043c.<\/p>\n<p>  \u0418\u0442\u0430\u043a, index.html:  <\/p>\n<pre><code class=\"html\">&lt;!DOCTYPE html&gt; &lt;html lang=&quot;en&quot;&gt;  &lt;head&gt;      &lt;meta charset=&quot;utf-8&quot;&gt;     &lt;link rel=&quot;shortcut icon&quot; href=&quot;favicon.ico?&quot; \/&gt;      &lt;!-- JQUERY 2.1.4 --&gt;     &lt;script src=&quot;vendors\/jquery-2.1.4.js&quot;&gt;&lt;\/script&gt;     &lt;!-- BOOTSTRAP 3.3.5 --&gt;     &lt;link rel=&quot;stylesheet&quot; href=&quot;vendors\/bootstrap.css&quot;&gt;     &lt;link rel=&quot;stylesheet&quot; href=&quot;vendors\/bootstrap-theme.css&quot;&gt;     &lt;script src=&quot;vendors\/bootstrap.js&quot;&gt;&lt;\/script&gt;     &lt;!-- ANGULARJS 1.4.7 --&gt;     &lt;script src=&quot;vendors\/angular.js&quot;&gt;&lt;\/script&gt;     &lt;script src=&quot;vendors\/angular-route.js&quot;&gt;&lt;\/script&gt;     &lt;!--     &lt;script src=&quot;https:\/\/code.jquery.com\/jquery-2.1.4.min.js&quot;&gt;&lt;\/script&gt;     &lt;link rel=&quot;stylesheet&quot; href=&quot;https:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.5\/css\/bootstrap.min.css&quot;&gt;     &lt;link rel=&quot;stylesheet&quot; href=&quot;https:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.5\/css\/bootstrap-theme.min.css&quot;&gt;     &lt;script src=&quot;https:\/\/maxcdn.bootstrapcdn.com\/bootstrap\/3.3.5\/js\/bootstrap.min.js&quot;&gt;&lt;\/script&gt;     &lt;script src=&quot;https:\/\/ajax.googleapis.com\/ajax\/libs\/angularjs\/1.4.7\/angular.min.js&quot;&gt;&lt;\/script&gt;     &lt;script src=&quot;https:\/\/code.angularjs.org\/1.4.7\/angular-route.min.js&quot;&gt;&lt;\/script&gt;     --&gt;      &lt;!-- angular-google-gapi --&gt;     &lt;!-- https:\/\/github.com\/maximepvrt\/angular-google-gapi\/releases --&gt;     &lt;script src=&quot;vendors\/angular-google-gapi.js&quot;&gt;&lt;\/script&gt;     &lt;!-- ngProgress --&gt;     &lt;!-- https:\/\/github.com\/VictorBjelkholm\/ngProgress --&gt;     &lt;script src=&quot;vendors\/ngprogress.js&quot;&gt;&lt;\/script&gt;     &lt;link rel=&quot;stylesheet&quot; href=&quot;vendors\/ngProgress.css&quot;&gt;     &lt;!-- angular-google-gapi --&gt;     &lt;!-- https:\/\/github.com\/maximepvrt\/angular-google-gapi\/releases --&gt;     &lt;script src=&quot;vendors\/angular-google-gapi.js&quot;&gt;&lt;\/script&gt;      &lt;!--  ~~~ MY APP ~~~ --&gt;     &lt;!-- main app module --&gt;     &lt;script src=&quot;js\/app.js&quot;&gt;&lt;\/script&gt;     &lt;!-- controllers --&gt;     &lt;script src=&quot;js\/simpleformcontroller.js&quot;&gt;&lt;\/script&gt;     &lt;script src=&quot;js\/authformcontroller.js&quot;&gt;&lt;\/script&gt;     &lt;!-- --&gt;     &lt;title&gt;Cloud Endpoints Frontend&lt;\/title&gt;  &lt;\/head&gt;  &lt;body ng-app=&quot;myApp&quot;&gt;      &lt;ng-view&gt;&lt;\/ng-view&gt;  &lt;\/body&gt;  &lt;\/html&gt;  <\/code><\/pre>\n<p>  \u041c\u044b \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b\u0438 <a href=\"https:\/\/code.angularjs.org\/1.4.7\/docs\/api\">AngularJS<\/a> \u0441 \u043c\u043e\u0434\u0443\u043b\u0435\u043c (\u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u043d\u0430\u0431\u043e\u0440\u0430) <a href=\"https:\/\/code.angularjs.org\/1.4.7\/docs\/api\/ngRoute\">ngRoute<\/a>.<\/p>\n<p>  \u0410 \u0442\u0430\u043a\u0436\u0435, \u0434\u043b\u044f \u0447\u0442\u043e\u0431\u044b \u0441\u0430\u0439\u0442 \u0438\u043c\u0435\u043b \u0434\u0440\u0443\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0432\u0438\u0434, \u0434\u043e\u0431\u0430\u0432\u0438\u043c <a href=\"http:\/\/getbootstrap.com\">Bootstrap<\/a> (+<a href=\"https:\/\/jquery.com\">jQuery<\/a>), \u0438 AngularJS \u043c\u043e\u0434\u0443\u043b\u044c <a href=\"https:\/\/github.com\/VictorBjelkholm\/ngProgress\">ngProgress<\/a>. \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 (progress bar), \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0445\u043e\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432.<\/p>\n<p>  \u041c\u044b \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u043b\u0438 angualrjs-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u043a \u00abmyApp\u00bb () \u0438 \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044e \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 ( &lt;ng-view&gt;&lt;\/ng-view&gt; ), \u0438 \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u0434\u0432\u0430 angularjs-\u043a\u043e\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430: js\/simpleformcontroller.js \u0438 js\/authformcontroller.js, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438 \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0438 \u0431\u0435\u0437 \u043e\u043d\u043e\u0439.<\/p>\n<p>  \u041c\u043e\u0434\u0443\u043b\u044c angular-google-gapi \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439, \u0438 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u0434\u0430\u043b\u0435\u0435.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c app.js:  <\/p>\n<pre><code class=\"javascript\">'use strict';  (     function () {         \/\/ create main module         var app = angular.module(&quot;myApp&quot;, [                 'ngRoute',   \/\/ https:\/\/code.angularjs.org\/1.4.7\/docs\/api\/ngRoute                 'ngProgress' \/\/ https:\/\/github.com\/victorbjelkholm\/ngprogress             ]         );         \/\/ routes         app.config(function ($routeProvider) {                 $routeProvider.when('\/', {                     templateUrl: &quot;templates\/simpleform.html&quot;,                     controller: &quot;SimpleFormController&quot;                 }).when('\/auth\/', {                         templateUrl: &quot;templates\/authform.html&quot;,                         controller: &quot;AuthFormController&quot;                     })                     .otherwise({redirectTo: '\/'})             }         );     }() );  <\/code><\/pre>\n<p>  \u0418 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 js\/simpleformcontroller.js:  <\/p>\n<pre><code class=\"javascript\">'use strict';  (     function() {          var SimpleFormController = function($scope, $http, ngProgressFactory) {              $scope.progressbar = ngProgressFactory.createInstance();             $scope.progressbar.setColor('blue');              $scope.data = {}; \/\/ data from form (ng-model=&quot;data. ...&quot;)              \/\/ $http configuration object             \/\/ https:\/\/code.angularjs.org\/1.4.7\/docs\/api\/ng\/service\/$http#usage             $scope.postReq = {                 method: 'POST',                 url: 'https:\/\/hello-habrahabr-api.appspot.com\/_ah\/api\/myApi\/v1\/register',                 data: $scope.data \/\/ 'data' for POST             };              $scope.getReq = {                 method: 'GET',                 url: 'https:\/\/hello-habrahabr-api.appspot.com\/_ah\/api\/myApi\/v1\/getgreeting',                 params: $scope.data \/\/ 'params:' for GET             };              $scope.actionPost = function() {                 $scope.progressbar.start();                 console.log(&quot;request sent:&quot;); \/\/ for testing                 console.log($scope.postReq); \/\/ for testing                 \/\/ AJAX request:                 \/\/ $http(req).then(function(){...}, function(){...});                 $http($scope.postReq).then(function(response) {                         \/\/ success:                         $scope.progressbar.complete();                         $scope.serverresponse = response;                         $scope.errormessage = null;                         console.log(&quot;response received:&quot;);                         console.log(response);                     }, \/\/ comma operator, see: https:\/\/developer.mozilla.org\/en\/docs\/Web\/JavaScript\/Reference\/Operators\/Comma_Operator                     function(response) {                         \/\/ error:                         $scope.progressbar.complete();                         $scope.errormessage = response;                         $scope.serverresponse = null;                         console.log(&quot;get Error form server:&quot;);                         console.log(response);                     });             };              $scope.actionGet = function() {                 $scope.progressbar.start();                 console.log(&quot;request sent:&quot;); \/\/ for testing                 console.log($scope.getReq); \/\/ for testing                 \/\/ AJAX request:                 \/\/ $http(req).then(function(){...}, function(){...});                 $http($scope.getReq).then(function(response) {                         \/\/ success:                         $scope.progressbar.complete();                         $scope.serverresponse = response;                         $scope.errormessage = null;                         console.log(&quot;response received:&quot;);                         console.log(response);                     }, \/\/ comma operator, see: https:\/\/developer.mozilla.org\/en\/docs\/Web\/JavaScript\/Reference\/Operators\/Comma_Operator                     function(response) {                         \/\/ error:                         $scope.progressbar.complete();                         $scope.errormessage = response;                         $scope.serverresponse = null;                         console.log(&quot;get Error form server:&quot;);                         console.log(response);                     });             };              $scope.clear = function() {                 $scope.serverresponse = null;                 $scope.errormessage = null;                 $scope.data = null;             };         };          \/\/ $inject property annotation         \/\/ see: https:\/\/code.angularjs.org\/1.4.7\/docs\/guide\/di         SimpleFormController.$inject = ['$scope', '$http', 'ngProgressFactory'];          angular.module('myApp')             .controller('SimpleFormController', SimpleFormController);      }());  <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a: \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043c\u043e\u0434\u0443\u043b\u044c \u00abMyApp\u00bb, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u00abSimpleFormController\u00bb \u0438 \u0432 \u043d\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f GET \u0438 POST \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043a &#8216;myApi API&#8217; (\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u043e\u0434\u043e\u043c \u0432 \u0444\u0430\u0439\u043b\u0435 YourFirstAPI.java ) \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043e\u043a, \u043d\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d templates\/simpleform.html \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 html-\u0444\u043e\u0440\u043c\u0430 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a API \u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u043e\u0442\u0432\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430:<\/p>\n<pre><code class=\"html\">&lt;div class=&quot;container&quot;&gt;     &lt;!-- Navigation Bar  --&gt;     &lt;nav class=&quot;navbar navbar-inverse&quot;&gt;         &lt;a class=&quot;navbar-brand&quot; href=&quot;#\/&quot;&gt;Front-end for Cloud Endpoints API&lt;\/a&gt;         &lt;ul class=&quot;nav navbar-nav&quot;&gt;             &lt;li class=&quot;active&quot;&gt;&lt;a href=&quot;#\/&quot;&gt;Home&lt;\/a&gt;&lt;\/li&gt;             &lt;li&gt;&lt;a href=&quot;#\/auth\/&quot;&gt;Auth&lt;\/a&gt;&lt;\/li&gt;         &lt;\/ul&gt;     &lt;\/nav&gt;     &lt;!-- Form --&gt;     &lt;form&gt;         &lt;fieldset&gt;             &lt;legend style=&quot;font-weight: bold;&quot;&gt;Submit your data to server&lt;\/legend&gt;             &lt;p&gt;                 &lt;label&gt; Name:                     &lt;input ng-model=&quot;data.name&quot;&gt;                 &lt;\/label&gt;             &lt;\/p&gt;             &lt;label&gt; Age:                 &lt;p&gt;                     &lt;input type=&quot;range&quot; min=&quot;0&quot; max=&quot;120&quot; step=&quot;1&quot; ng-model=&quot;data.age&quot;&gt;                 &lt;\/p&gt;                 &lt;p&gt;                     &lt;input ng-model=&quot;data.age&quot; name=&quot;ageNumber&quot; class=&quot;col-md-3&quot;&gt;                     &lt;span class=&quot;col-md-5&quot;&gt;years old&lt;\/span&gt;                 &lt;\/p&gt;             &lt;\/label&gt;             &lt;br&gt;             &lt;label&gt;                 &lt;p&gt; Is a human:                     &lt;input type=&quot;checkbox&quot; ng-model=&quot;data.ishuman&quot; name=&quot;data.ishuman&quot;&gt;                 &lt;\/p&gt;             &lt;\/label&gt;         &lt;\/fieldset&gt;         &lt;input type=&quot;button&quot; value=&quot;Submit GET&quot; ng-click=&quot;actionGet()&quot;&gt;         &lt;input type=&quot;button&quot; value=&quot;Submit POST&quot; ng-click=&quot;actionPost()&quot;&gt;         &lt;input type=&quot;reset&quot; ng-click=&quot;clear()&quot;&gt;     &lt;\/form&gt;     &lt;!-- Server Response --&gt;     &lt;br&gt;     &lt;div class=&quot;panel panel-default&quot;&gt;         &lt;div ng-hide=&quot;(serverresponse != null || errormessage != null)&quot; class=&quot;panel-body&quot;&gt;             &lt;p&gt;&lt;\/p&gt;             &lt;br&gt;             &lt;p&gt;&lt;\/p&gt;             &lt;br&gt;         &lt;\/div&gt;         &lt;div ng-show=&quot;serverresponse != null&quot; class=&quot;panel-body&quot;&gt;             &lt;p&gt;Response from server: &lt;\/p&gt;             &lt;p&gt;                 {{ serverresponse.data.message }} and your number is: {{serverresponse.data.usernumber}}             &lt;\/p&gt;         &lt;\/div&gt;         &lt;div ng-show=&quot;errormessage != null&quot; class=&quot;panel-body&quot;&gt;             &lt;p&gt;Error from server: &lt;\/p&gt;             &lt;p&gt;                 {{errormessage.data.error.message}}             &lt;\/p&gt;         &lt;\/div&gt;     &lt;\/div&gt; &lt;\/div&gt;  <\/code><\/pre>\n<p>  \u0418\u0442\u043e\u0433\u043e \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435: index.html, templates\/simpleform.html, js\/app.js, js\/simpleformcontroller.js<\/p>\n<p>  \u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 src\/main\/webapp\/:  <\/p>\n<pre><code class=\"bash\">python -m SimpleHTTPServer <\/code><\/pre>\n<p>  \u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/e38\/154\/a95\/e38154a958ad94c7416f91e906d69135.png\" alt=\"image\"\/><\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/51a\/8af\/f2d\/51a8aff2dfe15e27b32e372c59bf4806.png\" alt=\"image\"\/><\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u0441\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u2014 \u0434\u0435\u043f\u043b\u043e\u0438\u043c.<\/p>\n<h1> \u0414\u043e\u0441\u0442\u0443\u043f \u043a API \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043b\u043e\u0433\u0438\u043d\u0430-\u043f\u0430\u0440\u043e\u043b\u044f \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 Google (OAuth 2.0)<\/h1>\n<h2> \u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0431\u044d\u043a\u0435\u043d\u0434\u0430 <\/h2>\n<p>  \u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0432 \u0431\u044d\u043a\u0435\u043d\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (\u0443 \u043d\u0430\u0441 \u044d\u0442\u043e \u0431\u044b\u043b hello-habrahabr-api ) \u0432 \u043c\u0435\u043d\u044e:<br \/>  APIs &#038; auth -&gt; Credentials -&gt; Add Credentials -&gt; OAuth 2.0 Client ID<br \/>  \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441\u0430 \u0434\u043e\u043c\u0435\u043d\u043e\u0432 \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 Javascript \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a API (Authorized JavaScript origins) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f OAuth 2.0 \u043e\u0442 Google, \u0442.\u0435. \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043f\u0440\u043e\u043f\u0438\u0448\u0435\u043c hello-habrahabr-webapp.appspot.com \u0438\/\u0438\u043b\u0438 \u0441\u0432\u043e\u0439 \u0434\u043e\u043c\u0435\u043d \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 SSL \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u044b, \u043a\u0430\u043a \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u043b\u043e\u0441\u044c \u0432\u044b\u0448\u0435. \u0415\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043d\u0438\u0442\u044c\u0441\u044f \u0441 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c localhost + \u043d\u043e\u043c\u0435\u0440 \u043f\u043e\u0440\u0442\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <a href=\"http:\/\/localhost\">localhost<\/a>:8000<\/p>\n<p>  \u0412 \u043f\u043e\u043b\u0435 &#8216;Name&#8217; \u0432\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0435 \u0438\u043c\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#8216;Web Client&#8217;, \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043a\u043d\u043e\u043f\u043a\u043e\u0439 \u00abSave\u00bb:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/676\/d8b\/b0d\/676d8bb0dd8415fced352bf334bb69dc.png\" alt=\"image\"\/><\/p>\n<p>  \u041d\u0443\u0436\u043d\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u043e\u043b\u044f \u00abClient ID\u00bb, \u0432\u0438\u0434\u0430: 647700180043-m8et0au4vhgiv2n4iqr2hssn0mkkl7q0.apps.googleusercontent.com, \u0438\u043b\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c JSON-\u0444\u0430\u0439\u043b \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043a\u043b\u0438\u043a\u043d\u0443\u0432 \u043f\u043e \u043f\u0438\u043a\u0442\u043e\u0433\u0440\u0430\u043c\u043c\u0435, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435 \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u0430 \u043a\u0440\u0430\u0441\u043d\u044b\u043c.<\/p>\n<p>  \u0412 \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0441 API (\u0443 \u043d\u0430\u0441 \u044d\u0442\u043e hello-habrahabr-api) \u0432 \u0444\u0430\u0439\u043b\u0435 Constants.java: WEB_CLIENT_ID \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 Client ID, \u0430 EMAIL_SCOPE \u2014 \u00ab<a href=\"https:\/\/www.googleapis.com\/auth\/userinfo.email\">www.googleapis.com\/auth\/userinfo.email<\/a>\u00bb:  <\/p>\n<pre><code class=\"java\">package com.appspot.hello_habrahabr_api;  import com.google.api.server.spi.Constant;  \/**  * Contains the client IDs and scopes for allowed clients consuming your API.  *\/ public class Constants {     public static final String WEB_CLIENT_ID = &quot;647700180043-m8et0au4vhgiv2n4iqr2hssn0mkkl7q0.apps.googleusercontent.com&quot;;     public static final String ANDROID_CLIENT_ID = &quot;replace this with your Android client ID&quot;;     public static final String IOS_CLIENT_ID = &quot;replace this with your iOS client ID&quot;;     public static final String ANDROID_AUDIENCE = WEB_CLIENT_ID;      public static final String EMAIL_SCOPE = &quot;https:\/\/www.googleapis.com\/auth\/userinfo.email&quot;;      public static final String API_EXPLORER_CLIENT_ID = Constant.API_EXPLORER_CLIENT_ID; } <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c \u043d\u0430\u0448 OAuth2Api.java, \u0432 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0438  <a href=\"http:\/\/habrahabr.ru\/users\/api\/\" class=\"user_link\">Api<\/a> \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c:  <\/p>\n<pre><code class=\"java\">        scopes = {Constants.EMAIL_SCOPE},         clientIds = {Constants.WEB_CLIENT_ID, Constants.API_EXPLORER_CLIENT_ID}, <\/code><\/pre>\n<p>  \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043e\u0442 \u0432\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 Client ID (\u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043a\u043b\u0438\u0435\u043d\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 Client ID, \u043d\u043e \u0438 \u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441 \u0434\u043e\u043c\u0435\u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 APIs &#038; auth \u2014 Credentials) \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c email. \u0415\u0441\u043b\u0438 \u044d\u0442\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0432 OAuth2Api.java, \u0442\u043e \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b API \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u043e\u0439 401. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u044c Constants.API_EXPLORER_CLIENT_ID, \u0442\u043e \u043f\u0440\u0438 \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0432 API Explorer, \u0442.\u0435. \u0432\u0435\u0431-\u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 \u0432\u0438\u0434\u0430 {\u043f\u0440\u043e\u0435\u043a\u0442 ID}.appspot.com\/_ah\/api\/explorer \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430 401 (\u0442\u043e \u0435\u0441\u0442\u044c <a href=\"http:\/\/stackoverflow.com\/questions\/3297048\/403-forbidden-vs-401-unauthorized-http-responses\">\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/a>)<\/p>\n<p>  OAuth2Api.java \u0432 \u043d\u043e\u0432\u043e\u0439 \u0440\u0435\u0434\u0430\u043a\u0446\u0438\u0438:  <\/p>\n<pre><code class=\"java\">package com.appspot.hello_habrahabr_api;  \/**  * explore on: https:\/\/apis-explorer.appspot.com\/apis-explorer\/?base=https:\/\/hello-habrahabr-api.appspot.com\/_ah\/api#p\/oAuth2Api\/v1\/  *\/  import com.google.api.server.spi.config.Api; import com.google.api.server.spi.config.ApiMethod; import com.google.api.server.spi.config.ApiMethod.HttpMethod; import com.google.api.server.spi.response.UnauthorizedException; import com.google.appengine.api.users.User; import com.google.appengine.repackaged.com.google.gson.Gson;  import java.util.Random; import java.util.logging.Logger;  @Api(name = &quot;oAuth2Api&quot;, \/\/ The api name must match '[a-z]+[A-Za-z0-9]*'         version = &quot;v1&quot;,         scopes = {Constants.EMAIL_SCOPE},         clientIds = {Constants.WEB_CLIENT_ID, Constants.API_EXPLORER_CLIENT_ID},         description = &quot;API using OAuth2&quot;) public class OAuth2Api {      @SuppressWarnings(&quot;unused&quot;)     private static final Logger LOG = Logger.getLogger(OAuth2Api.class.getName());      @ApiMethod(             name = &quot;getUserInfo&quot;,             path = &quot;getuserinfo&quot;,             httpMethod = HttpMethod.POST     )     @SuppressWarnings(&quot;unused&quot;)     public MessageToUser getUserInfo(final User user, final UserForm userForm)             throws UnauthorizedException {          if (user == null) {             LOG.warning(&quot;User not logged in&quot;);             throw new UnauthorizedException(&quot;Authorization required&quot;);         }          MessageToUser messageToUser = new MessageToUser();         Gson gson = new Gson();         messageToUser.setMessage(                 &quot;Hi, &quot; +                         userForm.getName() +                         &quot;, your data from Google: &quot; +                         gson.toJson(user)         );         Random random = new Random();         messageToUser.setUsernumber(random.nextInt(100) + 1);         messageToUser.setIsregistered(true);          return messageToUser;     } }  <\/code><\/pre>\n<p>  \u041c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 API \u0432 \u0432 API Explorer, \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0443.<\/p>\n<h2> \u0424\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 <\/h2>\n<p>  \u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a API \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 Google \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 <a href=\"https:\/\/developers.google.com\/api-client-library\/javascript\/\">API Client Library for JavaScript<\/a>, \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0432\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442\u0435 AngularJS \u043c\u043e\u0434\u0443\u043b\u044c <a href=\"https:\/\/github.com\/maximepvrt\/angular-google-gapi\">angular-google-gapi<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e \u0441\u0443\u0442\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043e\u0431\u0435\u0440\u0442\u043a\u0443 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u0435\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441 AngularJS \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u043c. \u0411\u0430\u0437\u043e\u0432\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044e \u043c\u043e\u0434\u0443\u043b\u044f \u0441\u043c. \u043d\u0430 <a href=\"https:\/\/github.com\/maximepvrt\/angular-google-gapi\">github.com\/maximepvrt\/angular-google-gapi<\/a><\/p>\n<p>  \u041c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438  \u0432 index.html<\/p>\n<p>  \u041d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c \u0432 \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f ( var app = angular.module(&#8216;myApp&#8217;, [&#8216;angular-google-gapi&#8217;]); ), \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e app.run (\u2026 ).<br \/>  \u0412\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a (js\/app.js):  <\/p>\n<pre><code class=\"javascript\">'use strict';  (     function () {          \/\/ create main module         var app = angular.module(&quot;myApp&quot;, [             'ngRoute', \/\/ https:\/\/code.angularjs.org\/1.4.7\/docs\/api\/ngRoute             'ngProgress', \/\/ https:\/\/github.com\/victorbjelkholm\/ngprogress             'angular-google-gapi' \/\/ https:\/\/github.com\/maximepvrt\/angular-google-gapi\/ - add app.run() after app.config()         ]);          \/\/ routes         app.config(function ($routeProvider) {             $routeProvider.when('\/', {                 templateUrl: &quot;templates\/simpleform.html&quot;,                 controller: &quot;SimpleFormController&quot;             }).when('\/auth\/', {                 templateUrl: &quot;templates\/authform.html&quot;,                 controller: &quot;AuthFormController&quot;             }).otherwise({redirectTo: '\/'})         });          app.run(['GAuth', 'GApi', 'GData', '$rootScope',             function (GAuth,                       GApi,                       GData,                       $rootScope) {                 $rootScope.gdata = GData; \/\/                  var CLIENT = '647700180043-m8et0au4vhgiv2n4iqr2hssn0mkkl7q0.apps.googleusercontent.com';                 var BASE = 'https:\/\/hello-habrahabr-api.appspot.com\/_ah\/api';                 GApi.load('oAuth2Api', 'v1', BASE);                 GAuth.setClient(CLIENT);                  \/\/ see: https:\/\/github.com\/maximepvrt\/angular-google-gapi\/issues\/8                 GAuth.setScope(&quot;https:\/\/www.googleapis.com\/auth\/userinfo.email&quot;);                  GAuth.checkAuth().then(                     function () {                         \/\/ action if it's possible to authenticate user at startup of the application                         console.log(&quot;user authenticated, $rootScope.gapi.user: &quot;);                         console.log(console.log($rootScope.gapi.user));                     },                     function () {                         \/\/ action if it's impossible to authenticate user at startup of the application                         console.log(&quot;user not authenticated, $rootScope.gapi.user: &quot;);                         console.log(console.log($rootScope.gapi.user));                     }                 );                  $rootScope.login = function () { \/\/ shows auth window from Google                     GAuth.login().then(                         function () {                             console.log('user logged in');                             console.log(console.log($rootScope.gapi.user));                         });                 };                  \/*                  *  As stated on                  *  https:\/\/cloud.google.com\/appengine\/docs\/java\/endpoints\/consume_js:                  *  &quot;There is no concept of signing out using the JS client library,                  *  but you can emulate the behavior if you wish by any of these methods:                  *  - Resetting the UI to the pre signed-in state.                  *  - Setting any signed-in variables in your application logic to false                  *  - Calling gapi.auth.setToken(null);&quot; \/\/ &lt;- *                  * *\/                 $rootScope.logout = function () {                     GAuth.logout().then(                         function () {                             console.log('user logged out');                             console.log(console.log($rootScope.gapi.user));                         });                 };             }         ]);     }() );  <\/code><\/pre>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 login() \u0438 logout() \u043c\u044b \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043b\u0438 \u0432 &#8216;$rootScope&#8217;, \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e, \u043d\u043e \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u044f\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u043a\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u044d\u0442\u0438 \u0440\u0430\u0437\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438)<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 js\/authformcontroller.js:  <\/p>\n<pre><code class=\"javascript\">'use strict';  (     function () {          var AuthFormController = function ($scope, $rootScope, $http, GApi, GAuth, ngProgressFactory) {              $scope.progressbar = ngProgressFactory.createInstance();             $scope.progressbar.setColor('#00F');              $scope.data = {}; \/\/ object to store form data              $scope.authrequest = function () {                  $scope.progressbar.start();                 GAuth.checkAuth().then(                     function () {                         \/\/ if it's possible to authenticate user                         GApi.executeAuth( \/\/ execute request                             'oAuth2Api',                             'getUserInfo',                             $scope.data \/\/ data to send to server                             )                             .then(function (resp) {  \/\/ receive response                                 $scope.userinfofromserver = resp;                                 console.log(&quot;GApi.executeAuth() get resp:&quot;);                                 console.log(resp);                                 $scope.progressbar.complete();                             });                     },                     function () {                         \/\/ if it's impossible to authenticate user                         $scope.userinfofromserver = {};                         $scope.userinfofromserver.message = 'User not logged in ';                         console.log(&quot;GAuth.checkAuth() - failed: &quot;);                         console.log(console.log($rootScope.gapi.user));                         $scope.progressbar.complete();                     }                 );             };              $scope.clear = function () {                 $scope.userinfofromserver = null;                 $scope.data = null;             };          };          \/\/ $inject property annotation         \/\/ see: https:\/\/code.angularjs.org\/1.4.7\/docs\/guide\/di         AuthFormController.$inject = ['$scope', '$rootScope', '$http', 'GApi', 'GAuth', 'ngProgressFactory'];          angular.module('myApp')             .controller('AuthFormController', AuthFormController);      }()  );  <\/code><\/pre>\n<p>  \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0447\u0442\u043e \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c GApi.executeAuth(), \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c GAuth.checkAuth() \u2014 \u044d\u0442\u043e \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u0441\u0430\u043c\u0438\u043c \u0430\u0432\u0442\u043e\u0440\u043e\u043c \u043c\u043e\u0434\u0443\u043b\u044f, \u043d\u043e \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u043b\u043e\u0433\u0438\u0447\u043d\u044b\u043c, GApi.executeAuth() \u2014 \u043e\u0431\u043d\u043e\u0432\u0438\u0442 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u043b\u0433\u043e\u0433\u043e \u043f\u0435\u0440\u0438\u043e\u0434\u0430 \u0431\u0435\u0437\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 \u0438 \u0442.\u043f.<\/p>\n<p>  \u0412 $rootScope \u0443 \u043d\u0430\u0441 \u0442\u0435\u043f\u0435\u0440\u044c \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442 gapi.user, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0435\u043d\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435:   <\/p>\n<ul>\n<li>user.email<\/li>\n<li>user.picture (\u0430\u0432\u0430\u0442\u0430\u0440 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, url \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443)<\/li>\n<li>user.id (Google id (\u043d\u043e\u043c\u0435\u0440))<\/li>\n<li>user.name (\u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0438\u043b\u0438 \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, \u0442\u043e email)<\/li>\n<li>user.link (\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f Google+, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442)<\/li>\n<\/ul>\n<p>  \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432 \u0448\u0430\u0431\u043b\u043e\u043d\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0435\u043d\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0444\u043e\u0442\u043e \u0438 email, \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u044d\u0442\u0438\u043c \u0432 templates\/authform.html:  <\/p>\n<pre><code class=\"html\">&lt;div class=&quot;container&quot;&gt;     &lt;!-- Navigation Bar  --&gt;     &lt;nav class=&quot;navbar navbar-inverse&quot;&gt;         &lt;a class=&quot;navbar-brand&quot; href=&quot;#\/&quot;&gt;Front-end for Cloud Endpoints API&lt;\/a&gt;         &lt;ul class=&quot;nav navbar-nav&quot;&gt;             &lt;li&gt;&lt;a href=&quot;#\/&quot;&gt;Home&lt;\/a&gt;&lt;\/li&gt;             &lt;li class=&quot;active&quot;&gt;&lt;a href=&quot;#\/auth\/&quot;&gt;Auth&lt;\/a&gt;&lt;\/li&gt;         &lt;\/ul&gt;         &lt;!--  --&gt;         &lt;ul class=&quot;nav navbar-nav navbar-right&quot;&gt;             &lt;li&gt;                 &lt;a ng-show=&quot;gapi.user&quot; href=&quot;&quot; class=&quot;navbar-brand&quot; style=&quot;padding-top: 0;&quot;&gt;                     &lt;img src=&quot;{{gapi.user.picture}}&quot; class=&quot;navbar-brand&quot;                          style=&quot;padding-top: 0; padding-bottom: 0;&quot;&gt;&lt;\/a&gt;             &lt;\/li&gt;         &lt;\/ul&gt;         &lt;!--  --&gt;         &lt;ul class=&quot;nav navbar-nav navbar-right&quot;&gt;             &lt;!--  --&gt;             &lt;li ng-show=&quot;!gapi.user&quot; class=&quot;active&quot;&gt;                 &lt;a href=&quot;&quot; ng-click=&quot;login()&quot;&gt;login&lt;\/a&gt;             &lt;\/li&gt;             &lt;!--  --&gt;             &lt;li ng-show=&quot;gapi.user&quot;&gt;                 &lt;a href=&quot;&quot;&gt;{{gapi.user.email}}&lt;\/a&gt;             &lt;\/li&gt;             &lt;li ng-show=&quot;gapi.user&quot;&gt;                 &lt;a href=&quot;&quot; ng-click=&quot;logout()&quot;&gt;logout&lt;\/a&gt;             &lt;\/li&gt;         &lt;\/ul&gt;     &lt;\/nav&gt;     &lt;!-- Form --&gt;     &lt;form&gt;         &lt;fieldset&gt;             &lt;legend style=&quot;font-weight: bold;&quot;&gt;Submit your request to server&lt;\/legend&gt;             &lt;p&gt;                 &lt;label&gt; Your name:                     &lt;input ng-model=&quot;data.name&quot;&gt;                 &lt;\/label&gt;             &lt;\/p&gt;         &lt;\/fieldset&gt;         &lt;input type=&quot;button&quot; value=&quot;Auth request&quot; ng-click=&quot;authrequest()&quot;&gt;         &lt;input type=&quot;reset&quot; ng-click=&quot;clear()&quot;&gt;     &lt;\/form&gt;     &lt;!-- Server Response --&gt;     &lt;br&gt;      &lt;div class=&quot;panel panel-default&quot; style=&quot;font-weight: bold;&quot; &gt;         &lt;!--  --&gt;         &lt;div ng-hide=&quot;(userinfofromserver != null)&quot; class=&quot;panel-body&quot;&gt;             &lt;p&gt;&lt;\/p&gt;             &lt;br&gt;              &lt;p&gt;&lt;\/p&gt;             &lt;br&gt;         &lt;\/div&gt;         &lt;!--  --&gt;         &lt;div ng-show=&quot;userinfofromserver&quot; class=&quot;panel-body&quot;              style=&quot;&quot;&gt;             &lt;p&gt; User's data from server (reg # {{userinfofromserver.usernumber}}): &lt;\/p&gt;              &lt;p&gt;{{userinfofromserver.message}}&lt;\/p&gt;         &lt;\/div&gt;         &lt;!--  --&gt;     &lt;\/div&gt; &lt;\/div&gt; <\/code><\/pre>\n<p>  \u041f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u0438\u043c \u0434\u043e\u043c\u0430\u0448\u043d\u044e\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0430\u0439\u0442\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/ageyev\/cloud-endpoints-tutorial\/master\/habrahabr\/images2\/Selection_022.png\" alt=\"image\"\/><\/p>\n<p>  \u0412 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0441\u043a\u0440\u0438\u043f\u0442 \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0441\u0440\u0430\u0437\u0443 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u043e\u043a\u0430 \u00ab\u043d\u0435\u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0439\u00bb.<br \/>  \u0418\u0434\u0435\u043c \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 &#8216;Auth&#8217;:<br \/>  <img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/ageyev\/cloud-endpoints-tutorial\/master\/habrahabr\/images2\/Selection_023.png\" alt=\"image\"\/><br \/>  \u0412\u0432\u043e\u0434\u0438\u043c \u0438\u043c\u044f \u0432 \u043f\u043e\u043b\u0435 &#8216;Your name&#8217; \u0438 \u0436\u043c\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 &#8216;Auth request&#8217;:<br \/>  <img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/ageyev\/cloud-endpoints-tutorial\/master\/habrahabr\/images2\/Selection_024.png\" alt=\"image\"\/><br \/>  \u0422\u0435\u043f\u0435\u0440\u044c \u043b\u043e\u0433\u0438\u043d\u0438\u043c\u0441\u044f (\u0441\u0441\u044b\u043b\u043a\u0430 &#8216;login&#8217; \u043d\u0430 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438), \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c Google:<br \/>  <img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/ageyev\/cloud-endpoints-tutorial\/master\/habrahabr\/images2\/Selection_025.png\" alt=\"image\"\/><br \/>  \u041f\u043e\u0441\u043b\u0435 \u043b\u043e\u0433\u0438\u043d\u0430 \u043d\u0430\u0448\u0430 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u043f\u0430\u043d\u0435\u043b\u044c \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u043e\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u0437 \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 Google, email \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0438\u043b\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u0438 \u0441\u0441\u044b\u043b\u043a\u0443 &#8216;logout&#8217;.<br \/>  \u0415\u0441\u043b\u0438 \u043c\u044b \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043d\u043e\u0432\u0430 \u043f\u043e\u0448\u043b\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 (\u043a\u043d\u043e\u043f\u043a\u043e\u0439 &#8216;Auth request&#8217;), \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0442\u0432\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043a\u0430\u043a \u043f\u043e\u0434\u043e\u0431\u0430\u0435\u0442 \u0437\u0430\u043b\u043e\u0433\u0438\u043d\u0435\u043d\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e:<br \/>  <img decoding=\"async\" src=\"https:\/\/raw.githubusercontent.com\/ageyev\/cloud-endpoints-tutorial\/master\/habrahabr\/images2\/Selection_026.png\" alt=\"image\"\/><\/p>\n<p>  \u0422\u0430\u043a\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u044f\u0437\u044c \u0432\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u043e \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u043e\u043c\u0443 \u043a\u0430\u043d\u0430\u043b\u0443 \u0438 \u0441 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0431\u0435\u0437 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u0438 \u043d\u0430 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u041a\u0430\u043a \u044f \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u043e\u0441\u044c \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0442\u0440\u0435\u043d\u0434\u043e\u043c \u0441\u0442\u0430\u043d\u0435\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0438\u043d-\u043f\u0430\u0440\u043e\u043b\u044c \u043d\u0430 \u0441\u0430\u0439\u0442\u0430\u0445 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 <a href=\"http:\/\/oauth.net\/2\/\">OAuth 2.0<\/a> \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u0432.<\/p>\n<h3>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b:<\/h3>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/cloud.google.com\/appengine\/docs\/java\/endpoints\/\">Cloud Endpoints Tutorial from Google<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/appengine\/docs\/java\/endpoints\/annotations\">Endpoint Annotations<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/appengine\/docs\/java\/javadoc\/\">Google App Engine Java API (Javadoc)<\/a><\/li>\n<li><a href=\"https:\/\/cloud.google.com\/solutions\/angularjs-cloud-endpoints-recipe-for-building-modern-web-applications\">AngularJS + Cloud Endpoints \u2014 A Recipe for Building Modern Web Applications<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/maximepvrt\/angular-google-gapi\/tree\/gh-pages\">\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c angular-google-gapi, \u043e\u0442 \u0430\u0432\u0442\u043e\u0440\u0430 \u043c\u043e\u0434\u0443\u043b\u044f (\u043d\u0430 GitHub)<\/a><\/li>\n<\/ul>\n<div class=\"clear\"><\/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=\"http:\/\/habrahabr.ru\/post\/270459\/\"> http:\/\/habrahabr.ru\/post\/270459\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       \u0427\u0430\u0441\u0442\u044c \u043f\u0435\u0440\u0432\u0430\u044f: <a href=\"http:\/\/habrahabr.ru\/post\/268863\/\">Google Cloud Endpoints \u043d\u0430 Java: \u0420\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e. \u0447. 1<\/a><\/p>\n<p>  \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 <a href=\"https:\/\/cloud.google.com\/appengine\/docs\/java\/endpoints\/\">Google Cloud Endpoints \u0441 Java<\/a>, \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0435\u0447\u044c \u043f\u043e\u0439\u0434\u0435\u0442 \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430 \u043a \u043d\u0430\u0448\u0435\u043c\u0443 API.<\/p>\n<p>  \u0412 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u043c\u0441\u044f \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f:<\/p>\n<p>  <a href=\"https:\/\/angularjs.org\/\">AngularJS<\/a>, \u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0431\u0449\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e <a href=\"http:\/\/getbootstrap.com\/\">Bootstrap<\/a> \u0438\u043b\u0438 <a href=\"http:\/\/foundation.zurb.com\/\">Foundation<\/a>.<\/p>\n<p>  \u041f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u0434\u043b\u044f \u0434\u0435\u043f\u043b\u043e\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/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-268486","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/268486","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=268486"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/268486\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=268486"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=268486"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=268486"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}