Sending Email via Gmail with 2-Step Authentication from AngularJS Frontend to Spring Boot Backend

Sending Email via Gmail with 2-Step Authentication from AngularJS Frontend to Spring Boot Backend

Sending Email via Gmail with 2-Step Authentication from AngularJS Frontend to Spring Boot Backend

In this tutorial, I’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’t, then I’ll take you through a couple extra steps. Then, I’ll show you how you can tie everything together with a frontend written in AngularJS 1.6.

Firstly, make sure you have your Spring Boot application’s Maven POM configured correctly:

[code language=”xml”]
<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

</dependencies>
[/code]

Now, you need to configure your application.properties. This is what needs to be added:

[code language=”bash”]
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=testing123@gmail.com
spring.mail.password=abcdef123456
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
[/code]

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:

[code language=”bash”]
{
"timestamp": 1521418235937,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.mail.MailAuthenticationException",
"message": "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 – gsmtp\n",
"path": "/email/"
}
[/code]

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:

Next, you are ready to create a REST controller to send emails. Here is an example:

[code language=”java”]
/**
* Copyright (c) 2017 CoySoft, All Rights Reserved
* Contains proprietary and confidential information owned by CoySoft.
*/
package com.coysoft.email;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.coysoft.email.model.EmailModel;

/**
* Service to send emails.
*
* @author kcoy – Kevin Coy
* @version 1.0
*/
@RestController
@RequestMapping("/email")
public class EmailController {

private static final Logger LOGGER = LoggerFactory.getLogger(EmailController.class);

@Autowired
private JavaMailSender javaMailSender;

@RequestMapping(value = "/", method = RequestMethod.POST, consumes = "application/json")
public Response sendEmail(@RequestBody EmailModel emailModel) {
LOGGER.info("Sending email");

MimeMessage mail = javaMailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(mail, true);
helper.setTo("testing123@gmail.com");
helper.setReplyTo(emailModel.getEmail());
helper.setFrom(emailModel.getEmail());
helper.setSubject(emailModel.getSubject());
helper.setText("From: " + emailModel.getUsername() + "\n" + emailModel.getMessage());
} catch (MessagingException e) {
LOGGER.error("Failed to send email: " + emailModel.toString(), e);
} finally {}
javaMailSender.send(mail);

return Response.accepted().build();
}
}

[/code]

This controller uses an object called EmailModel. Using Lombok, the class is very simple and compact:

[code language=”java”]
@XmlRootElement
@Data
@AllArgsConstructor
@NoArgsConstructor
public class EmailModel {

private String username;

private String email;

private String subject;

private String message;
}
[/code]

Now, you are ready to start your Spring Boot application and test the endpoint. Using Postman, we can easily test like so:

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 email-service.js like this:

[code language=”javascript”]
(function( angular ) {
angular.module( ‘contact’ )
.factory( ’email’, function( $filter, $http) {
var baseUrl = ‘http://localhost:8181/email/’,
filter = $filter( ‘filter’ );

return {
submit : submit
};

function submit( emailPayload ) {
var p1 = $http.post( ‘http://localhost:8181/email/’, emailPayload);
return p1;
}

} );

})( angular );
[/code]

We can take this further by creating a contact page to call this service. Here is the controller contact-us-main.component.js:

[code language=”javascript”]
(function( angular ) {
angular.module( ‘contact’ )
.component( ‘contactUsMain’, {
templateUrl: ‘app/contact-us/contact-us-main.component.html’,
controller : ContactUsMainController
} );

function ContactUsMainController( $log, $state, $stateParams, email ) {
var ctrl = this;

ctrl.reset = reset;
ctrl.submit = submit;

reset();

function reset() {
console.log("console log reset");
$log.debug("in reset");
ctrl.model = {};

if(ctrl.form) {
ctrl.form.$setPristine();
}
}

function submit(model) {
email.submit(model).then(
function(response) {
alert(‘Thanks for contacting us!’);
},
function(response) {
alert(‘We are currently experience a technical issue. Please try again in a moment’);
}
)

}
}
})( angular );
[/code]

Next, here is the view contact-us-main.component.html:

[code language=”html”]
<div class="row">
<div class="col-md-12 container" ui-view>
<h3>Contact Us</h3>

<form class="form-horizontal" name="$ctrl.form" novalidate ng-show="!token">
<div class="form-group">
<div class="col-md-2">
<label>Your Name</label>
</div>
<div class="col-md-5">
<input type="text" name="username" class="form-control" ng-model="$ctrl.model.username" required>
<div class="alert alert-danger" ng-show="($ctrl.form.username.$touched || $ctrl.form.$submitted) && $ctrl.form.username.$error.required">
Your name is required
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-2">
<label>Your Email Address</label>
</div>
<div class="col-md-5">
<input type="email" name="email" class="form-control" ng-model="$ctrl.model.email" ng-pattern="/^[_a-zA-Z0-9]+(\.[_a-zA-Z0-9]+)*@[a-z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,24})$/" required>
<div class="alert alert-danger" ng-show="($ctrl.form.email.$touched || $ctrl.form.$submitted) && $ctrl.form.email.$error.required">
Your email address is required
</div>
<div class="alert alert-danger" ng-show="($ctrl.form.email.$touched || $ctrl.form.$submitted) && !$ctrl.form.email.$valid">
Your email is not valid
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-2">
<label>Subject</label>
</div>
<div class="col-md-5">
<input type="text" name="subject" class="form-control" ng-model="$ctrl.model.subject" required>
<div class="alert alert-danger" ng-show="($ctrl.form.subject.$touched || $ctrl.form.$submitted) && $ctrl.form.subject.$error.required">
Subject is required
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-2">
<label>Your Message</label>
</div>
<div class="col-md-5">
<textarea rows="5" name="message" class="form-control" ng-model="$ctrl.model.message" ng-minlength="25" required></textarea>
<div class="alert alert-danger" ng-show="($ctrl.form.message.$touched || $ctrl.form.$submitted) && $ctrl.form.message.$error.required">
Your message is required
</div>
<div class="alert alert-danger" ng-show="($ctrl.form.message.$touched || $ctrl.form.$submitted) && !$ctrl.form.message.$valid">
Your message is not valid. Minimum of 25 characters.
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-5">
<input type="submit" value="Submit" class="btn btn-primary" ng-click="$ctrl.submit($ctrl.model)" ng-disabled="$ctrl.form.$invalid"/>
<button class="btn btn-default" ng-click="$ctrl.reset()">Reset</button>
</div>
</div>
</form>

<div class="alert alert-success" ng-show="token">
You have successfully registered with token: {{token}}!!!
</div>

</div>
</div>
[/code]

Please note that the default pattern used by AngularJS to check email addresses is not correct in my opinion (and many others). Hence, a custom regular expression is used instead: /^[_a-zA-Z0-9]+(\.[_a-zA-Z0-9]+)*@[a-z0-9-]+(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,24})$/.

Here is what it looks like in the browser:

Contact Us Page to send Email

Contact Us Page to send Email

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.

18 Comments:

  1. Aaavrutgvf https://xmqrgjvcpr.com/

    Aaavrutgvf

  2. Good info. Lucky me I reach on your website by accident, I bookmarked it.

  3. You actually make it seem really easy along with your presentation but I find this topic to be actually one thing that I believe I might never understand. It kind of feels too complicated and extremely broad for me. I am taking a look ahead for your subsequent put up, I will try to get the hold of it!

  4. Thank you a lot for giving everyone such a spectacular opportunity to check tips from this website. It is usually so lovely and jam-packed with a lot of fun for me and my office mates to visit the blog at least thrice in 7 days to find out the newest secrets you will have. And of course, we’re actually pleased for the outstanding principles you serve. Selected two tips in this posting are certainly the most beneficial we have had.

  5. I am just commenting to make you be aware of of the useful discovery our princess enjoyed going through yuor web blog. She even learned many things, which include what it is like to have an excellent coaching spirit to get many more clearly comprehend some grueling matters. You undoubtedly exceeded people’s expectations. Thanks for coming up with these necessary, safe, explanatory as well as unique tips on this topic to Lizeth.

  6. I needed to compose you one very little note so as to thank you very much over again over the precious tips you have provided on this page. It was certainly unbelievably generous with people like you to grant extensively just what many individuals might have supplied for an e-book to earn some dough on their own, certainly now that you might have done it in the event you desired. The advice likewise acted to be the fantastic way to know that the rest have the identical dream like my own to realize more and more with regard to this matter. Certainly there are some more pleasurable situations in the future for many who look into your blog.

  7. My husband and i have been quite more than happy Jordan could finish off his investigations through your precious recommendations he was given using your web page. It’s not at all simplistic to simply happen to be giving out methods that other people have been selling. We really realize we now have the blog owner to give thanks to for that. These explanations you made, the easy website navigation, the relationships you will make it possible to create – it is all fantastic, and it’s letting our son in addition to us do think this situation is thrilling, which is highly vital. Thank you for all the pieces!

  8. I am also writing to make you be aware of what a outstanding discovery our girl encountered using your webblog. She realized a lot of issues, which include what it is like to possess a marvelous helping character to make most people effortlessly know selected grueling subject matter. You undoubtedly exceeded my expected results. Many thanks for distributing such priceless, dependable, informative not to mention unique thoughts on that topic to Sandra.

  9. I precisely desired to thank you very much yet again. I am not sure what I could possibly have followed without the entire tricks shown by you regarding such question. It had been an absolute fearsome matter for me personally, but coming across a well-written strategy you resolved the issue made me to cry for joy. I’m grateful for your advice and in addition have high hopes you realize what an amazing job you were putting in educating many people all through a site. I’m certain you haven’t met any of us.

  10. Fashion More provides in-depth journalism and insight into the news and trends impacting the fashion

  11. San Gabriel Valley News is the local news source for Los Angeles County

  12. Bazopril is a blood pressure supplement featuring a blend of natural ingredients to support heart health

  13. Pineal XT is a revolutionary supplement that promotes proper pineal gland function and energy levels to support healthy body function.

  14. Sumatra Slim Belly Tonic is an advanced weight loss supplement that addresses the underlying cause of unexplained weight gain. It focuses on the effects of blue light exposure and disruptions in non-rapid eye movement (NREM) sleep.

  15. The ProNail Complex is a meticulously-crafted natural formula which combines extremely potent oils and skin-supporting vitamins.

  16. I think other website proprietors should take this internet site as an example , very clean and great user pleasant style.

  17. whoah this blog is great i love reading your posts. Keep up the good work! You know, many people are hunting around for this information, you can aid them greatly.

Leave a Reply

Your email address will not be published. Required fields are marked *