Category Archives: Programming

How to integrate reCaptcha with Spring Boot Application

In this post, I want to show how to integrate ReCaptcha in a Spring Boot application. This will be an important step if you have forms in your application and if those forms are publicly available on the internet. You can face a lot of spams or bots trying to fill those forms. To avoid these spams from bots, ReCaptcha is of utmost importance.

Google offers a reCaptcha service that we will integrate with Spring Boot application to stop bots from submitting the forms in our application.

Registration with Google for ReCaptcha

Google offers a reCaptcha service that developers can use in their applications. As part of this implementation, we will register our service in Google APIs so that Google can provide us credentials to use while calling its service.

We can register our site at Google Recaptcha Administration. This registration will provide us with site-key and site-secret.

Now as part of Spring boot application, we can store these credentials in application.properties file as below:

# ====================================================================================
# Google reCaptcha Settings
# ====================================================================================
google.recaptcha.key.site=site-key
google.recaptcha.key.secret=site-secret

We will make these properties available through a spring bean object in our application, so we can use them when we call Google Recaptcha Service.

UI changes to display ReCaptcha box

Now to display Recaptcha box on your form, we will add the following code in our templates where our public form resides. In this case, I am putting Recaptcha box in Contact Us and Sign Up pages as those are publicly available forms.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <title>Renters Feedback</title>

    <!-- other scripts and stylesheets -->
    <script src='https://www.google.com/recaptcha/api.js'></script>

</head>
<body>

<form method = "post" id="contactus" th:action="@{/contact}">
<!--- other code to display contact us form -->
<div class="g-recaptcha" th:attr="data-sitekey=${@captchaSettings.getSite()}"></div><br/><br/>
<span id="captchaError" class="alert alert-danger col-sm-4" style="display:none"></span>
</form>

</body>
</html>

 

Server-side handling of ReCaptcha

So as we have a widget on our form. When a user completes a challenge and submits the form, the request will be sent to the server containing an encoded site key and a unique string that identifies user’s challenge completion.

But on the server side, we can’t just assume and trust what the user has submitted. So we need to verify this captcha challenge by sending a request to Google API at https://www.google.com/recaptcha/api/siteverify by passing captcha response we have received.

If the verification is successful, the json response from API will contain a success parameter.

If the verification fails, then an application will throw an exception and reCaptcha library will instruct a client to create a new challenge.

One thing to understand here is that we limit how many attempts a client can make to reCaptcha challenge. The reason for this is to avoid any kind of DoS attack. Of course, this is precautionary and elementary step. We implement ReCaptchaAttemptService to block if a client tries to use the challenge for more than 4 attempts.

Demo of the complete workflow of ReCaptcha

Conclusion

In this post, we showed how we can use google reCaptcha service to integrate a reCaptcha widget in a form that is publicly available to avoid bots spams. From the security perspective, this is an important step and developers should take into account this important feature for their web applications.

References

  1. Recaptcha with Spring Boot Application – Recaptcha With Spring Boot Application
  2. Protecting Spring Boot application with Google Recaptcha – Protecting Spring Boot Application

 

 

Techstack Framework for RentersFeedback

As a developer, we make different choices based on what is available to us and what we know. But are those choices always better? They may not or they may. It really depends. In this post, I describe the techstack framework that I used to build Renters Feedback.

You can read my post, how I came up with an idea to build an application for renters feedback.

I wanted to describe the process of the choices I made to choose a tech stack framework for building the application. Considering my expertise in Spring Boot, it was a default choice to use to build this application. There are other factors I took into account like the ease of coding, ease of deploying as a microservice-based application in the cloud, and docker.

Development Framework For Renters Feedback

For developing the application, my focus was on the re-usability of code. Since I have written few applications as part of this blog using Spring Boot, there was authentication, login forms, sign up forms, most of that code was readily available. One thing I have to think through for RentersFeedback was database modeling.

Database Framework for Renters Feedback

For developing a database based application, I used mysql as a development database. In production, I changed that to postgresql . 

Why database change? 

Heroku support for mysql wasn’t straightforward, so I preferred what was available by default and it was postgresql. I have to do a few changes to mysql scripts. I could have automated these scripts through liquibase, but I preferred not to for the first version of the product. In the future, when I plan to add more changes to the database model, I will add liquibase-based scripts.

Authentication Scheme

There were some questions about why a user needs to login on a RentersFeedback website. Well, someone has to post those reviews before people can browse it. You need to login if you want to post a review.

The easiest choice was to have form-based login even though it is getting old and not safe. I still feel most users would use email to login. User passwords are stored in an encrypted and hashed format in the database.

Another mechanism, I decided to add, was OAuth2 OpenId protocol by using Google API for the same. It was easy to implement and something I have expertise in.

I could add other social logins, but I prefer to keep it simple and if the need arises, I will add those logins in the future.

Using Google API, made me use Redis Cache. I wasn’t planning to use cache since the application is still in nascent stages, but now it is there, so future scaling would be easier from a performance perspective.

User Interface

The user interface was built using Spring Boot provided thymeleaf templates along with Twitter’s Bootstrap CSS library and javascript library. For the search feature, I have used javascript library of Google search APIs.

After deploying the application on Heroku, I came across a few issues about having forms available publicly. To avoid spams, I will be adding Captcha on those forms. I will show how to use reCaptcha APIs in the next post.

To allow users to reset the password, I have used Spring Boot Email system. This was an easy implementation once you know how the forgot your password flow works.

Deployment Environment

I used Heroku to deploy my application. Heroku has great documentation. It’s very easy to sync up with your GitHub repository. So if you push your changes to GitHub, it will sync up to build and deploy on Heroku.

Questions

Choosing the right tech stack framework for your application can be a difficult task if you are a beginner.  Since I have experience in building applications, choosing this techstack framework for Renters Feedback was a straightforward choice. If you have any questions about implementation, why I used certain technology, and how it can be improved, you can post a comment on this blog and I will answer those questions.

 

RentersFeedback.com

RentersFeedback is a brainchild from a tweet that a friend tweeted back in August:

Tweet from a renter

Based on this tweet, I thought it would be nice if renters have some say about landlords. Around the same time, my girlfriend was looking for an apartment/house to rent. Even though we found a place, we were not sure if it’s a good place. And there were no reviews about this place. On the first impression, the house didn’t look like a place where anybody has lived in a long time, but we made our decision and went ahead with it. It would have been nice if there was a review of this place.

I am sure when most people are looking for places to rent, they use services like Padmapper or Zillow which offers the easiest way to find places based on area, requirements, budget, other facilities. But none of these applications offer a review system.

What this will solve?

Renters Feedback will solve the much-needed place to provide reviews about the places that people are renting. This will help future renters to look for good places to rent. This will also make landlords and rental management companies more accountable. I hope Renters Feedback can help renters with reviews for the places they want to rent.

What about Yelp?

Yelp.com has been providing reviews of restaurants, small businesses, and other things, but rarely of a standalone house to be rented or a rental management company. Yelp has done a tremendous job, but it lacks in this one area.

Why an application with a single functionality?

Less is more. Simple functionality matters in long terms than a complicated one. In marketing, there is a term affordance that refers to the perceived and actual properties of the thing, primarily those fundamental properties that determine how the thing could be used. A single functionality of the application will help users to navigate and use the application efficiently.

Techstack

To build RentersFeedback.com, I have used Spring Boot Microservice based architecture. I have implemented the current user interface using Twitter Bootstrap, CSS, Javascript, Google Javascript API, and Thymeleaf. Backend is written using Java and database supported.

Using Redis for caching, Google for OAuth2 authentication along with regular authentication.

Heroku.com is my choice of the cloud platform to launch the application. It offers an easy way to assemble all the needed services like database, Redis, and the server itself.

One future change for this might be to move the user interface to reactjs. Something that is currently I am working on.

Feedback

I would love it if you could use the application and would appreciate any feedback.  Subscribe to my blog to find out more about renters’ feedback.

 

Deploying Spring Boot Application to Heroku

Heroku is a platform as a service (PAAS) that helps developers to build, deploy, and run applications on a cloud platform. Deploying Spring Boot application to Heroku is a straight forward process. I will describe this process in this post. There are actually multiple ways to deploy a spring boot application. The simplest way to deploy the application is to use maven built jar file and run that jar file on Heroku server.

In my previous post, I showed how to use Spring session in your Spring Boot application.

Before I show one of these two methods to deploy the application, we assume that you have created an account on Heroku.com, if not first please create an account and download Heroku-CLI (Command Line Interface). I also assume that you have git downloaded and installed.

Initial Deployment with Heroku

Once you have Heroku account and Command Line Interface downloaded, let’s start deploying the Spring Boot app with repository.

Create an application directory on your development environment.


git init
git add .
git commit -m "first commit"

Now you can either create an app in Heroku through web-interface OR through Heroku CLI.

heroku create rentersfeedback would create the application in Heroku.

As part of this post, I am deploying an alpha version of my application rentersfeedback.com

Once you add the source code to the directory, we can push the repository to heroku.  Every time you push the repository to Heroku, Heroku’s builder will build the application and launch it.

git push heroku master

Despite this initial push, we don’t have the application ready to use yet.

Database Configuration

For this application, I will be using Postgres database. Heroku offers a couple of ways to add database as an add-on.

Once Postgres database is added, go to settings -> view credentials  this will provide us database credentials.

Now we can access the database server through pgAdmin Postgres Administration and create database and database tables for our application.

Back in Heroku web-interface, if you go to the application settings page, click on reveal Config Vars and set up the following variables


SPRING_DATASOURCE_URL= 
SPRING_DATASOURCE_USERNAME= 
SPRING_DATASOURCE_PASSWORD= 
SPRING_DATASOURCE_DRIVER-CLASS-NAME=org.postgresql.Driver 
SPRING_DATASOURCE_TYPE=org.apache.tomcat.jdbc.pool.DataSource 
SPRING_JPA_DATABASE-PLATFORM=org.hibernate.dialect.PostgreSQLDialect

As you can see that we are using datasource type as tomcat jdbc pool and not the standard hikariCP which Spring boot provides. To make sure to work this, we have to add a dependency of tomcat-jdbc as follows:


compile('org.apache.tomcat:tomcat-jdbc:9.0.29') 
compile('org.postgresql:postgresql:42.2.8')

If you don’t specify data source type as tomcat-jdbc, Heroku throws an error for Postgres database as below:

Caused by: java.lang.RuntimeException: Driver org.postgresql.Driver claims to not accept jdbcUrl

This will get our Spring Boot app to work with the Postgres database while deploying on Heroku.

Configuration of Gradle to build a jar file

So by default, Heroku supports maven. If you want to use Gradle to build your application, you can use the following guidelines.

Now if you push these changes to heroku and build the application, the application will throw the following error while starting up



2019-11-30T17:05:46.096985+00:00 heroku[api]: Deploy 291326d by xxx@gmail.com 
2019-11-30T17:05:46.097021+00:00 heroku[api]: Release v9 created by xxx@gmail.com 
2019-11-30T17:05:46.378258+00:00 heroku[slug-compiler]: Slug compilation started 
2019-11-30T17:05:46.378269+00:00 heroku[slug-compiler]: Slug compilation finished 
2019-11-30T17:05:46.755655+00:00 heroku[web.1]: State changed from crashed to starting 
2019-11-30T17:05:53.121398+00:00 heroku[web.1]: Starting process with command `java -Dserver.port=5000 -jar build/libs/myapp.jar` 
2019-11-30T17:05:54.260741+00:00 app[web.1]: Error: Unable to access jarfile build/libs/myapp.jar 
2019-11-30T17:05:54.784064+00:00 heroku[web.1]: State changed from starting to crashed 
2019-11-30T17:05:54.773714+00:00 heroku[web.1]: Process exited with status 1

To resolve this issue, I will add a task in my gradle script that will build a jar file when I deploy the application.


apply plugin: 'java' 

task stage(type: Copy, dependsOn: [clean, build]) { 
    from jar.archivePath into project.rootDir rename { 'app.jar' } 
} 

stage.mustRunAfter(clean) 

clean.doLast { 
   project.file('app.jar').delete() 
}

Setting up application.properties

We have deployed our application, configured database, and build script. Usually when spring boot application starts, it will access all the required variables from application.properties. So I will set up that file as follows:



# ==================================================================================== 
# = DATASOURCE 
# ==================================================================================== 
spring.datasource.url=${SPRING_DATASOURCE_URL} 
spring.datasource.username = ${SPRING_DATASOURCE_USERNAME} 
spring.datasource.password=${SPRING_DATASOURCE_PASSWORD} 
spring.datasource.driver-class-name=${SPRING_DATASOURCE_DRIVER-CLASS-NAME} 
spring.jpa.show-sql=true spring.jpa.properties.hibernate.dialect = ${SPRING_JPA_DATABASE-PLATFORM} 
spring.datasource.type=${SPRING_DATASOURCE_TYPE} 
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true 
# ==================================================================================== 
# = Server SSL 
# ==================================================================================== 
server.port = 7443 
security.require-ssl=true

Setting up a custom domain

Heroku offers an easy option with SSL, so if you choose that, it is a straightforward approach with Let’s Encrypt to automatically manage the SSL certificate.

Now to set up the custom domain, add your domain and heroku will provide the target DNS server. For your corresponding domain provider, you will add DNS setting for CNAME(for www) and ANAME (root domain). Wait for a few hours for this setting to take place.

Access the application

We are ready to access the application now. Once you have pushed all the required changes to Heroku repository, heroku will build the application and launch it.

Now if we access rentersfeedback.com, we will be able to see the application as follows:

Renters Feedback

References

  1. Deploying Spring boot application to Heroku – deploy spring boot app
  2. Deploying Gradle application to Heroku – Gradle applications to Heroku
  3. Custom domains in Heroku – Custom domains in Heroku

 

 

Forgot Password Feature in Spring Boot Application

In this post, we will show how to implement a forgot password feature for your Spring Boot Application. In my old post, I had shown how to create social login for an application.

Most web applications will have forgot password page and there are different policies about password creation and resetting the password. Overall, you can assume that user will forget a password and will need to reset password.

Flow for Forgot Password

  1. User visits login screen and clicks on forgot password option.
  2. User enters email address in forgot password box.
  3. On Server side, we verify if a user with that email exists or not.
  4. On Server side, we create a time-bound security reset token affiliated with that user and send it in an email, provided that the user exists.
  5. User receives an email to reset password.
  6. Once the user clicks the reset password link which includes the reset token.
  7. User redirects to a page where the user can reset the password.
  8. Then the user submits a new password along with reset token. Based on reset token, we first verify if the user is correct and then saves the new password.
  9. User redirects to login page.

Once now, we have described the flow, we can show how to implement this feature.

Forgot Password UI

A screen where user will enter email address to reset the password, will look like below:

Forgot Password

Once the user enters his email address, server side implementation will validate if a user with that email exists or not. In LoginController , this posting of Reset Password will look like below:


        String email = ServletUtil.getAttribute(request, "email");
        User user = userRepository.findUserByEmail(email);

        if(user == null)
        {
            model.addAttribute("error", "We didn't find this user");
            return "forgotpassword";
        }
        PasswordResetToken token = new PasswordResetToken();
        token.setToken(UUID.randomUUID().toString());
        token.setUser(user);
        token.setExpiryDate(30);
        passwordResetTokenRepository.save(token);
        
        Mail mail = new Mail();
        Map<String, Object> modelObj = new HashMap<>();
        modelObj.put("token",token);
        modelObj.put("user", user);
        String url =
                request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
        modelObj.put("resetUrl", url + "/resetpassword?token=" + token.getToken());
        mail.setModel(modelObj);
        emailService.sendEmail(mail);

As you see in this code token object is one-to-one mapped with user.  Once the user submits email address, we send him a password reset email with URL.

So this email will look like below:

Once the user clicks on the link from email, user will be redirected to a form to submit new password. When displaying the form, first the reset token will be validated if it has not expired and exists. GET request for reset form will present the form.

POST request will submit the form to reset user password.


    @GetMapping
    public String getPasswordResetPage(@RequestParam(required=false) String token, Model model)
    {
        PasswordResetToken passwordResetToken = passwordResetTokenRepository.findByToken(token);
        if(passwordResetToken == null)
        {
            model.addAttribute("error","Could not find reset token");
        }
        else if(passwordResetToken.isExpired())
        {
            model.addAttribute("error","Reset Token is expired");
        }
        else
        {
            model.addAttribute("token",passwordResetToken.getToken());
        }
        return "resetpassword";
    }

    @PostMapping
    public String handlePasswordReset(HttpServletRequest request, Model model)
    {
        String token = ServletUtil.getAttribute(request, "token");
        PasswordResetToken passwordResetToken = passwordResetTokenRepository.findByToken(token);
        User user = passwordResetToken.getUser();
        String password = ServletUtil.getAttribute(request, "password");
        String confirmPassword = ServletUtil.getAttribute(request, "confirmPassword");
        
        user.setPassword(updatedPassword);
        user.setPasswordConfirm(updatedPassword);
        userRepository.save(user);
        passwordResetTokenRepository.delete(passwordResetToken);

        return "redirect:/login?resetSuccess";

    }

After new password is saved, the reset token is deleted, so it can’t be reused.

Conclusion

In this post, we showed how to implement the user story of forgot password. There are usually different possibilities to reset the password. It mostly depends on what password policies you adapt.

References

  1. Forgot Password Feature – Forgot Password