
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
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.
Aaavrutgvf
Good info. Lucky me I reach on your website by accident, I bookmarked it.