{"id":450,"date":"2018-03-21T00:38:57","date_gmt":"2018-03-21T00:38:57","guid":{"rendered":"http:\/\/kevinmichaelcoy.com\/blog\/?p=450"},"modified":"2018-03-21T01:00:59","modified_gmt":"2018-03-21T01:00:59","slug":"sending-email-via-gmail-with-2-step-authentication-from-angularjs-frontend-to-spring-boot-backend","status":"publish","type":"post","link":"http:\/\/kevinmichaelcoy.com\/blog\/2018\/03\/21\/sending-email-via-gmail-with-2-step-authentication-from-angularjs-frontend-to-spring-boot-backend\/","title":{"rendered":"Sending Email via Gmail with 2-Step Authentication from AngularJS Frontend to Spring Boot Backend"},"content":{"rendered":"<div id=\"attachment_472\" style=\"width: 2058px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-472\" loading=\"lazy\" src=\"http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/Sending-Email-via-Gmail-with-2-Step-Authentication-from-AngularJS-Frontend-to-Spring-Boot-Backend.png\" alt=\"Sending Email via Gmail with 2-Step Authentication from AngularJS Frontend to Spring Boot Backend\" width=\"2048\" height=\"1152\" class=\"size-full wp-image-472\" srcset=\"http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/Sending-Email-via-Gmail-with-2-Step-Authentication-from-AngularJS-Frontend-to-Spring-Boot-Backend.png 2048w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/Sending-Email-via-Gmail-with-2-Step-Authentication-from-AngularJS-Frontend-to-Spring-Boot-Backend-300x169.png 300w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/Sending-Email-via-Gmail-with-2-Step-Authentication-from-AngularJS-Frontend-to-Spring-Boot-Backend-768x432.png 768w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/Sending-Email-via-Gmail-with-2-Step-Authentication-from-AngularJS-Frontend-to-Spring-Boot-Backend-1024x576.png 1024w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/Sending-Email-via-Gmail-with-2-Step-Authentication-from-AngularJS-Frontend-to-Spring-Boot-Backend-150x84.png 150w\" sizes=\"(max-width: 2048px) 100vw, 2048px\" \/><p id=\"caption-attachment-472\" class=\"wp-caption-text\">Sending Email via Gmail with 2-Step Authentication from AngularJS Frontend to Spring Boot Backend<\/p><\/div>\n<p>In this tutorial, I&#8217;ll show you how to configure Spring Boot to set up a REST Controller to send emails via Gmail. Plus, if you have 2-Step Authentication set up, which you should if you don&#8217;t, then I&#8217;ll take you through a couple extra steps. Then, I&#8217;ll show you how you can tie everything together with a frontend written in AngularJS 1.6.<\/p>\n<p>Firstly, make sure you have your Spring Boot application&#8217;s Maven POM configured correctly:<\/p>\n<p>[code language=&#8221;xml&#8221;]<br \/>\n\t&lt;dependencies&gt;<br \/>\n                &#8230;<br \/>\n\t\t&lt;dependency&gt;<br \/>\n\t\t\t&lt;groupId&gt;org.springframework.boot&lt;\/groupId&gt;<br \/>\n\t\t\t&lt;artifactId&gt;spring-boot-starter-mail&lt;\/artifactId&gt;<br \/>\n\t\t&lt;\/dependency&gt;<br \/>\n                &#8230;<br \/>\n\t&lt;\/dependencies&gt;<br \/>\n[\/code]<\/p>\n<p>Now, you need to configure your <code>application.properties<\/code>. This is what needs to be added:<\/p>\n<p>[code language=&#8221;bash&#8221;]<br \/>\nspring.mail.host=smtp.gmail.com<br \/>\nspring.mail.port=587<br \/>\nspring.mail.username=testing123@gmail.com<br \/>\nspring.mail.password=abcdef123456<br \/>\nspring.mail.properties.mail.smtp.auth=true<br \/>\nspring.mail.properties.mail.smtp.starttls.enable=true<br \/>\n[\/code]<\/p>\n<p>Of course, you will need to substitute your actual email address and your actual password to your Gmail account. Now, if you have 2-Step Authentication (ie, 2-Step Verification) configured on your Gmail account, you will need to create an application specific password. If you do not, you will see an error like the following:<\/p>\n<p>[code language=&#8221;bash&#8221;]<br \/>\n{<br \/>\n&quot;timestamp&quot;: 1521418235937,<br \/>\n&quot;status&quot;: 500,<br \/>\n&quot;error&quot;: &quot;Internal Server Error&quot;,<br \/>\n&quot;exception&quot;: &quot;org.springframework.mail.MailAuthenticationException&quot;,<br \/>\n&quot;message&quot;: &quot;Authentication failed; nested exception is javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at\\n535 5.7.8 https:\/\/support.google.com\/mail\/?p=BadCredentials i79sm6827128qkh.11 &#8211; gsmtp\\n&quot;,<br \/>\n&quot;path&quot;: &quot;\/email\/&quot;<br \/>\n}<br \/>\n[\/code]<\/p>\n<p>With that warning in place, lets just go ahead and mitigate ever seeing the aforementioned issue by creating an application specific password. Please go to the following page to create one:<\/p>\n<ul>\n<li><a href=\"https:\/\/myaccount.google.com\/apppasswords\">https:\/\/myaccount.google.com\/apppasswords<\/a> (<a href=\"https:\/\/support.google.com\/mail\/answer\/185833?hl=en\">instructions<\/a>)<\/li>\n<\/ul>\n<p>Next, you are ready to create a REST controller to send emails. Here is an example:<\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\n\/**<br \/>\n * Copyright (c) 2017 CoySoft, All Rights Reserved<br \/>\n * Contains proprietary and confidential information owned by CoySoft.<br \/>\n *\/<br \/>\npackage com.coysoft.email;<\/p>\n<p>import javax.mail.MessagingException;<br \/>\nimport javax.mail.internet.MimeMessage;<br \/>\nimport javax.ws.rs.core.Response;<\/p>\n<p>import org.slf4j.Logger;<br \/>\nimport org.slf4j.LoggerFactory;<br \/>\nimport org.springframework.beans.factory.annotation.Autowired;<br \/>\nimport org.springframework.mail.javamail.JavaMailSender;<br \/>\nimport org.springframework.mail.javamail.MimeMessageHelper;<br \/>\nimport org.springframework.web.bind.annotation.CrossOrigin;<br \/>\nimport org.springframework.web.bind.annotation.RequestBody;<br \/>\nimport org.springframework.web.bind.annotation.RequestMapping;<br \/>\nimport org.springframework.web.bind.annotation.RequestMethod;<br \/>\nimport org.springframework.web.bind.annotation.RestController;<\/p>\n<p>import com.coysoft.email.model.EmailModel;<\/p>\n<p>\/**<br \/>\n * Service to send emails.<br \/>\n *<br \/>\n * @author kcoy &#8211; Kevin Coy<br \/>\n * @version 1.0<br \/>\n *\/<br \/>\n@RestController<br \/>\n@RequestMapping(&quot;\/email&quot;)<br \/>\npublic class EmailController {<\/p>\n<p>    private static final Logger LOGGER = LoggerFactory.getLogger(EmailController.class);<\/p>\n<p>    @Autowired<br \/>\n    private JavaMailSender javaMailSender;<\/p>\n<p>    @RequestMapping(value = &quot;\/&quot;, method = RequestMethod.POST, consumes = &quot;application\/json&quot;)<br \/>\n    public Response sendEmail(@RequestBody EmailModel emailModel) {<br \/>\n        LOGGER.info(&quot;Sending email&quot;);<\/p>\n<p>        MimeMessage mail = javaMailSender.createMimeMessage();<br \/>\n        try {<br \/>\n            MimeMessageHelper helper = new MimeMessageHelper(mail, true);<br \/>\n            helper.setTo(&quot;testing123@gmail.com&quot;);<br \/>\n            helper.setReplyTo(emailModel.getEmail());<br \/>\n            helper.setFrom(emailModel.getEmail());<br \/>\n            helper.setSubject(emailModel.getSubject());<br \/>\n            helper.setText(&quot;From: &quot; + emailModel.getUsername() + &quot;\\n&quot; + emailModel.getMessage());<br \/>\n        } catch (MessagingException e) {<br \/>\n            LOGGER.error(&quot;Failed to send email: &quot; + emailModel.toString(), e);<br \/>\n        } finally {}<br \/>\n        javaMailSender.send(mail);<\/p>\n<p>        return Response.accepted().build();<br \/>\n    }<br \/>\n}<\/p>\n<p>[\/code]<\/p>\n<p>This controller uses an object called <code>EmailModel<\/code>. Using <a href=\"https:\/\/projectlombok.org\">Lombok<\/a>, the class is very simple and compact:<\/p>\n<p>[code language=&#8221;java&#8221;]<br \/>\n@XmlRootElement<br \/>\n@Data<br \/>\n@AllArgsConstructor<br \/>\n@NoArgsConstructor<br \/>\npublic class EmailModel {<\/p>\n<p>    private String username;<\/p>\n<p>    private String email;<\/p>\n<p>    private String subject;<\/p>\n<p>    private String message;<br \/>\n}<br \/>\n[\/code]<\/p>\n<p>Now, you are ready to start your Spring Boot application and test the endpoint. Using Postman, we can easily test like so:<\/p>\n<p><img loading=\"lazy\" class=\"aligncenter size-full wp-image-459\" src=\"http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/sending-email-via-postman-to-rest-controller.png\" alt=\"\" width=\"1956\" height=\"1052\" srcset=\"http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/sending-email-via-postman-to-rest-controller.png 1956w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/sending-email-via-postman-to-rest-controller-300x161.png 300w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/sending-email-via-postman-to-rest-controller-768x413.png 768w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/sending-email-via-postman-to-rest-controller-1024x551.png 1024w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/sending-email-via-postman-to-rest-controller-150x81.png 150w\" sizes=\"(max-width: 1956px) 100vw, 1956px\" \/><\/p>\n<p>Now, we know the backend of the application is up and running. Lets move on to getting our AngularJS code to use this. We can create a service called <code>email-service.js<\/code> like this:<\/p>\n<p>[code language=&#8221;javascript&#8221;]<br \/>\n(function( angular ) {<br \/>\n    angular.module( &#8216;contact&#8217; )<br \/>\n      .factory( &#8217;email&#8217;, function( $filter, $http) {<br \/>\n        var baseUrl = &#8216;http:\/\/localhost:8181\/email\/&#8217;,<br \/>\n        filter = $filter( &#8216;filter&#8217; );<\/p>\n<p>        return {<br \/>\n          submit  : submit<br \/>\n        };<\/p>\n<p>        function submit( emailPayload ) {<br \/>\n          var p1 = $http.post( &#8216;http:\/\/localhost:8181\/email\/&#8217;, emailPayload);<br \/>\n          return p1;<br \/>\n        }<\/p>\n<p>      } );<\/p>\n<p>    })( angular );<br \/>\n[\/code]<\/p>\n<p>We can take this further by creating a contact page to call this service. Here is the controller <code>contact-us-main.component.js<\/code>:<\/p>\n<p>[code language=&#8221;javascript&#8221;]<br \/>\n(function( angular ) {<br \/>\n  angular.module( &#8216;contact&#8217; )<br \/>\n    .component( &#8216;contactUsMain&#8217;, {<br \/>\n      templateUrl: &#8216;app\/contact-us\/contact-us-main.component.html&#8217;,<br \/>\n      controller : ContactUsMainController<br \/>\n    } );<\/p>\n<p>  function ContactUsMainController( $log, $state, $stateParams, email ) {<br \/>\n    var ctrl = this;<\/p>\n<p>    ctrl.reset = reset;<br \/>\n    ctrl.submit = submit;<\/p>\n<p>    reset();<\/p>\n<p>    function reset() {<br \/>\n      console.log(&quot;console log reset&quot;);<br \/>\n      $log.debug(&quot;in reset&quot;);<br \/>\n      ctrl.model = {};<\/p>\n<p>      if(ctrl.form) {<br \/>\n        ctrl.form.$setPristine();<br \/>\n      }<br \/>\n    }<\/p>\n<p>    function submit(model) {<br \/>\n        email.submit(model).then(<br \/>\n            function(response) {<br \/>\n                alert(&#8216;Thanks for contacting us!&#8217;);<br \/>\n            },<br \/>\n            function(response) {<br \/>\n                alert(&#8216;We are currently experience a technical issue. Please try again in a moment&#8217;);<br \/>\n            }<br \/>\n        )<\/p>\n<p>    }<br \/>\n  }<br \/>\n})( angular );<br \/>\n[\/code]<\/p>\n<p>Next, here is the view <code>contact-us-main.component.html<\/code>:<\/p>\n<p>[code language=&#8221;html&#8221;]<br \/>\n&lt;div class=&quot;row&quot;&gt;<br \/>\n  &lt;div class=&quot;col-md-12 container&quot; ui-view&gt;<br \/>\n    &lt;h3&gt;Contact Us&lt;\/h3&gt;<\/p>\n<p>    &lt;form class=&quot;form-horizontal&quot; name=&quot;$ctrl.form&quot; novalidate ng-show=&quot;!token&quot;&gt;<br \/>\n      &lt;div class=&quot;form-group&quot;&gt;<br \/>\n          &lt;div class=&quot;col-md-2&quot;&gt;<br \/>\n              &lt;label&gt;Your Name&lt;\/label&gt;<br \/>\n          &lt;\/div&gt;<br \/>\n          &lt;div class=&quot;col-md-5&quot;&gt;<br \/>\n              &lt;input type=&quot;text&quot; name=&quot;username&quot; class=&quot;form-control&quot; ng-model=&quot;$ctrl.model.username&quot; required&gt;<br \/>\n              &lt;div class=&quot;alert alert-danger&quot; ng-show=&quot;($ctrl.form.username.$touched || $ctrl.form.$submitted) &amp;&amp; $ctrl.form.username.$error.required&quot;&gt;<br \/>\n                  Your name is required<br \/>\n              &lt;\/div&gt;<br \/>\n          &lt;\/div&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n      &lt;div class=&quot;form-group&quot;&gt;<br \/>\n        &lt;div class=&quot;col-md-2&quot;&gt;<br \/>\n            &lt;label&gt;Your Email Address&lt;\/label&gt;<br \/>\n        &lt;\/div&gt;<br \/>\n        &lt;div class=&quot;col-md-5&quot;&gt;<br \/>\n            &lt;input type=&quot;email&quot; name=&quot;email&quot; class=&quot;form-control&quot; ng-model=&quot;$ctrl.model.email&quot; ng-pattern=&quot;\/^[_a-zA-Z0-9]+(\\.[_a-zA-Z0-9]+)*@[a-z0-9-]+(\\.[a-zA-Z0-9-]+)*(\\.[a-zA-Z]{2,24})$\/&quot; required&gt;<br \/>\n            &lt;div class=&quot;alert alert-danger&quot; ng-show=&quot;($ctrl.form.email.$touched || $ctrl.form.$submitted) &amp;&amp; $ctrl.form.email.$error.required&quot;&gt;<br \/>\n                Your email address is required<br \/>\n            &lt;\/div&gt;<br \/>\n            &lt;div class=&quot;alert alert-danger&quot; ng-show=&quot;($ctrl.form.email.$touched || $ctrl.form.$submitted) &amp;&amp; !$ctrl.form.email.$valid&quot;&gt;<br \/>\n              Your email is not valid<br \/>\n           &lt;\/div&gt;<br \/>\n        &lt;\/div&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n      &lt;div class=&quot;form-group&quot;&gt;<br \/>\n          &lt;div class=&quot;col-md-2&quot;&gt;<br \/>\n              &lt;label&gt;Subject&lt;\/label&gt;<br \/>\n          &lt;\/div&gt;<br \/>\n          &lt;div class=&quot;col-md-5&quot;&gt;<br \/>\n              &lt;input type=&quot;text&quot; name=&quot;subject&quot; class=&quot;form-control&quot; ng-model=&quot;$ctrl.model.subject&quot; required&gt;<br \/>\n              &lt;div class=&quot;alert alert-danger&quot; ng-show=&quot;($ctrl.form.subject.$touched || $ctrl.form.$submitted) &amp;&amp; $ctrl.form.subject.$error.required&quot;&gt;<br \/>\n                  Subject is required<br \/>\n              &lt;\/div&gt;<br \/>\n          &lt;\/div&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n      &lt;div class=&quot;form-group&quot;&gt;<br \/>\n          &lt;div class=&quot;col-md-2&quot;&gt;<br \/>\n              &lt;label&gt;Your Message&lt;\/label&gt;<br \/>\n          &lt;\/div&gt;<br \/>\n          &lt;div class=&quot;col-md-5&quot;&gt;<br \/>\n              &lt;textarea rows=&quot;5&quot; name=&quot;message&quot; class=&quot;form-control&quot; ng-model=&quot;$ctrl.model.message&quot; ng-minlength=&quot;25&quot; required&gt;&lt;\/textarea&gt;<br \/>\n              &lt;div class=&quot;alert alert-danger&quot; ng-show=&quot;($ctrl.form.message.$touched || $ctrl.form.$submitted) &amp;&amp; $ctrl.form.message.$error.required&quot;&gt;<br \/>\n                Your message is required<br \/>\n              &lt;\/div&gt;<br \/>\n              &lt;div class=&quot;alert alert-danger&quot; ng-show=&quot;($ctrl.form.message.$touched || $ctrl.form.$submitted) &amp;&amp; !$ctrl.form.message.$valid&quot;&gt;<br \/>\n                Your message is not valid. Minimum of 25 characters.<br \/>\n              &lt;\/div&gt;<br \/>\n          &lt;\/div&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n      &lt;div class=&quot;form-group&quot;&gt;<br \/>\n          &lt;div class=&quot;col-md-offset-2 col-md-5&quot;&gt;<br \/>\n              &lt;input type=&quot;submit&quot; value=&quot;Submit&quot; class=&quot;btn btn-primary&quot; ng-click=&quot;$ctrl.submit($ctrl.model)&quot; ng-disabled=&quot;$ctrl.form.$invalid&quot;\/&gt;<br \/>\n              &lt;button class=&quot;btn btn-default&quot; ng-click=&quot;$ctrl.reset()&quot;&gt;Reset&lt;\/button&gt;<br \/>\n          &lt;\/div&gt;<br \/>\n      &lt;\/div&gt;<br \/>\n  &lt;\/form&gt;<\/p>\n<p>  &lt;div class=&quot;alert alert-success&quot; ng-show=&quot;token&quot;&gt;<br \/>\n      You have successfully registered with token: {{token}}!!!<br \/>\n  &lt;\/div&gt;<\/p>\n<p>  &lt;\/div&gt;<br \/>\n&lt;\/div&gt;<br \/>\n[\/code]<\/p>\n<p>Please note that the default pattern used by AngularJS to check email addresses is not correct in my opinion (and <a href=\"https:\/\/stackoverflow.com\/questions\/24490668\/how-to-validate-email-id-in-angularjs-using-ng-pattern\">many others<\/a>). Hence, a custom regular expression is used instead: <code>\/^[_a-zA-Z0-9]+(\\.[_a-zA-Z0-9]+)*@[a-z0-9-]+(\\.[a-zA-Z0-9-]+)*(\\.[a-zA-Z]{2,24})$\/<\/code>.<\/p>\n<p>Here is what it looks like in the browser:<\/p>\n<div id=\"attachment_464\" style=\"width: 2346px\" class=\"wp-caption aligncenter\"><img aria-describedby=\"caption-attachment-464\" loading=\"lazy\" class=\"size-full wp-image-464\" src=\"http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/contact-us-page.png\" alt=\"Contact Us Page to send Email\" width=\"2336\" height=\"1246\" srcset=\"http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/contact-us-page.png 2336w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/contact-us-page-300x160.png 300w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/contact-us-page-768x410.png 768w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/contact-us-page-1024x546.png 1024w, http:\/\/kevinmichaelcoy.com\/blog\/wp-content\/uploads\/2018\/03\/contact-us-page-150x80.png 150w\" sizes=\"(max-width: 2336px) 100vw, 2336px\" \/><p id=\"caption-attachment-464\" class=\"wp-caption-text\">Contact Us Page to send Email<\/p><\/div>\n<p>I hope this gets you well on your way to being able to send emails from an AngularJS web application to a Spring Boot backend.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, I&#8217;ll show you how to configure Spring Boot to set up a REST Controller to send emails via Gmail. Plus, if you have 2-Step Authentication set up, which you should if you don&#8217;t, then I&#8217;ll take you through a couple extra steps. Then, I&#8217;ll show you how&#8230;<\/p>\n<p class=\"continue-reading-button\"> <a class=\"continue-reading-link\" href=\"http:\/\/kevinmichaelcoy.com\/blog\/2018\/03\/21\/sending-email-via-gmail-with-2-step-authentication-from-angularjs-frontend-to-spring-boot-backend\/\">Continue reading<i class=\"crycon-right-dir\"><\/i><\/a><\/p>\n","protected":false},"author":1,"featured_media":472,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[5,3],"tags":[335,336,290,317,333,334,337,235],"_links":{"self":[{"href":"http:\/\/kevinmichaelcoy.com\/blog\/wp-json\/wp\/v2\/posts\/450"}],"collection":[{"href":"http:\/\/kevinmichaelcoy.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/kevinmichaelcoy.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/kevinmichaelcoy.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/kevinmichaelcoy.com\/blog\/wp-json\/wp\/v2\/comments?post=450"}],"version-history":[{"count":20,"href":"http:\/\/kevinmichaelcoy.com\/blog\/wp-json\/wp\/v2\/posts\/450\/revisions"}],"predecessor-version":[{"id":473,"href":"http:\/\/kevinmichaelcoy.com\/blog\/wp-json\/wp\/v2\/posts\/450\/revisions\/473"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/kevinmichaelcoy.com\/blog\/wp-json\/wp\/v2\/media\/472"}],"wp:attachment":[{"href":"http:\/\/kevinmichaelcoy.com\/blog\/wp-json\/wp\/v2\/media?parent=450"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/kevinmichaelcoy.com\/blog\/wp-json\/wp\/v2\/categories?post=450"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/kevinmichaelcoy.com\/blog\/wp-json\/wp\/v2\/tags?post=450"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}