How to Implement 2Factor International OTP Sms in Spring Rest API

Posted By : Dipen Chawla | 28-Dec-2017

2Factor.in provides OTP Services, Transactional Services, Promotional Services and nowadays 2Factor is supporting foreign countries also and they have different pricing for their different countries.

2Factor has 2 to 6 seconds otp delivery and they use Routing Algorithm to Reroute Failed Messages.

The Best Feature of 2Factor.in is that user has to pay only for its delivered within 15 seconds and they have security is also very authentic as their data is private and mask numbers with 2Factor.

 

2Factor International OTP in Spring Rest API:

UserController.java:

This Otp functionality in add Mobile Number Controller which interact with User Service.

@RequestMapping(value = UrlMapping.ADD_MOBILE_NUMBER, method = RequestMethod.PUT)
    ResponseEntity<Object> addMobileNumber(@RequestParam Long mobileNumber,@RequestParam Long dialCode) {
        User loggedInuser = GenericUtils.getLoggedInUser();
        int response;
        try {
            response = userService.addMobileNumber(mobileNumber,loggedInuser.getId(), dialCode);
        } catch (Exception e) {
            return ResponseHandler.generateResponse(HttpStatus.BAD_REQUEST, true, e.getMessage(), null);
        }
        if (response > 0) {
            return ResponseHandler.generateResponse(HttpStatus.OK, false,
                    messageService.getMessage(Message.MOBILE_NUMBER_ADDED), mobileNumber);
        } else {
            return ResponseHandler.generateResponse(HttpStatus.BAD_REQUEST, true,
                    messageService.getMessage(Message.UNABLE_TO_ADD_MOBILE), null);
        }
    }

UserService.java:

This Service enable the functionality for international users and national users.

public int addMobileNumber(Long mobileNumber, long userId,Long dialCode) throws Exception {
 User user = userRepository.findById(userId);
 if (user != null ) {
 Security existingSecurityByMobile = securityRepository.findByMobileNumber(mobileNumber);
 if ((user.getSecurity().getIsMobileVerified() && user.getSecurity().getMobileNumber() != null
 && user.getSecurity().getMobileNumber().equals(mobileNumber))
 || (existingSecurityByMobile != null && existingSecurityByMobile.getIsMobileVerified() )) {
  throw new PersistenceException(messageService.getMessage(Message.USER_ENTERED_MOBILE_NUMBER_ALREADY_VERIFIED));
 } else {
  Random r = new Random();
  int code = (100000 + r.nextInt(900000));
  smsSenderUtil.sentOtpWithDialCode(code, mobileNumber, envConfiguration.getOtpTemplateName(),dialCode);
  OTP otp = new OTP(userId, mobileNumber, code);
  otpRepository.save(otp);
  MessageFormat.format(otpInternational,"+"+dialCode.toString()+mobileNumber.toString(),otp.getOtp().toString(),envConfiguration.getOtpTemplateName());
  return securityRepository.setMobileNumberwithDialCode(mobileNumber,dialCode,userId);
  }
  } else {
    throw new UsernameNotFoundException(messageService.getMessage(Message.USER_DOES_NOT_EXISTS));
  }
    }

SmsUtil.java

This Method provide the Response of the otp functionality.

public void sentOtpWithDialCode(int otp, Long mobileNumber, String template , Long dialCode) throws Exception {
  String url = envConfiguration.get2FactorOtpUrl() + "+" +dialCode + mobileNumber + "/" + otp + "/" + template;
  @SuppressWarnings("unchecked")
  Map<Object, Object> response = restTemplate.getForObject(url, HashMap.class);
  System.out.println("Success-"+response);
  if (response.get("Status").equals("Error")) {
  throw new Exception(response.get("Details").toString());
   }
    }

SmsRepository.java:

This is Repository which contains Spring Data JPA query for updating mobile number.

  @Transactional
  @Modifying
  @Query("update Security s set s.mobileNumber=?1,s.dialCode=?2,s.isMobileVerified=false where s.userId=?3 ")
int setMobileNumberwithDialCode(Long mobileNumber,Long dialCode,Long userId);

Verify Mobile.java:

This is Method Verifies the Mobile Number

public boolean verifyMobileNumber(int otp, long userId) throws InvalidOtpException {
        User user = userRepository.findById(userId);
        if (user != null) {
            OTP existingOtp = otpRepository.findByOtp(otp);
            if (existingOtp != null) {
                if (existingOtp.getIsDeleted() == false
                        && existingOtp.getMobileNumber().equals(user.getSecurity().getMobileNumber())) {
                    long timeDiffInSec = (new Date().getTime() - existingOtp.getCreatedDate().getTime()) / 1000;
                    if (timeDiffInSec <= 300) {
                        int updateResponse = securityRepository.verifyMobile(user.getId());
                        if (updateResponse > 0) {
                            int otpDeleteResp = otpRepository.deleteOtp(existingOtp.getId());
                            if (otpDeleteResp > 0) {
                                return true;
                            } else {
                                return false;
                            }
                        } else {
                            return false;
                        }
                    } else {
                        throw new InvalidOtpException(messageService.getMessage(Message.OTP_EXPIRED));
                    }
                } else {
                    throw new InvalidOtpException(messageService.getMessage(Message.OTP_INVALID));
                }
            } else {
                throw new InvalidOtpException(messageService.getMessage(Message.OTP_INVALID));
            }
        } else {
            throw new UsernameNotFoundException(messageService.getMessage(Message.USER_DOES_NOT_EXISTS));
        }
    }

 

About Author

Author Image
Dipen Chawla

Dipen is Java Developer and his keen interest is in Spring, Hibernate, Rest web-services, AngularJS and he is a self motivated person and loves to work in a team.

Request for Proposal

Name is required

Comment is required

Sending message..