Best way to integrate captcha in angularJS

12,623

Its very simple follow the steps...

<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
async defer></script>

<script>
    var onloadCallback = function() {
        widgetId1 = grecaptcha.render('example1', {
            'sitekey' : 'Site-Key-',
            'theme' : 'light'
        });
    };
</script>
<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
async defer>

Now at the form put it

<div id="example1"></div> 
<p style="color:red;">{{ captcha_status }}</p>

Validate with angular

if(grecaptcha.getResponse(widgetId1)==''){
    $scope.captcha_status='Please verify captha.';
    return;
}
Share:
12,623

Related videos on Youtube

EllisTheEllice
Author by

EllisTheEllice

Updated on June 22, 2022

Comments

  • EllisTheEllice
    EllisTheEllice about 2 years

    I'm relatively new to angularJS and I wonder what would be the cleanest solution to the following problem. Let's say I have a form such as follows

    <form name="contactform">
       <select id="salutation" name="salutation" required="true" ng-model="contactRequest.salutation"><option value="Herr" selected="">Herr</option><option value="Frau">Frau</option></select>
    
       <img width="255" height="70" alt="" src="/website/var/tmp/aed4d639a26c4614cdac2a967381c61c.png" name="captcha[img]"> 
    
       <captcha-reloader reload-url="/refresh-captcha" img-tag-name="captcha[img]" hidden-field-name="captcha[id]"></captcha-reloader>
    
       <input type="text" name="captcha[input]" required="true" ng-model="contactRequest.captcha.input">                
    
       <input type="text" style="display: none;" ng-model="contactRequest.captcha.id" value="aed4d639a26c4614cdac2a967381c61c" name="captcha[id]">   
    ...
    

    As you can see, it uses a directive to display a button which will reload the CAPTCHA. It is defined as

        myApp.directive('captchaReloader', function () {
        return {
            restrict: 'E',
            scope: {
                reloadUrl: '@',
                imgTagName: '@',
                hiddenFieldName: '@'
            }, //isolate scope
            template: '<a href="" ng-click="reloadCaptcha()" class="captcha-reload"></a>',
            link: function (scope, element, attrs) {
    
            },
            controller: function ($scope, $element, $attrs, $http) {
                $scope.reloadCaptcha = function () {
                    $http.get($attrs.reloadUrl).then(function (res) {
                        angular.element('img[name="' + $attrs.imgTagName + '"]').attr('src', res.data.imgSrc);
                        angular.element('input[name="' + $attrs.hiddenFieldName + '"]').val(res.data.id);
                        angular.element('input[name="' + $attrs.hiddenFieldName + '"]').trigger('input');
                    });
                };
            }
        };
    )};
    

    If I click on the button, the captcha image and value (hidden field) are updated. It works fine so far.

    Now, I want to handle form submission in controller (see methode below). If there is an error (server-side validation), the captcha has to be updated. I don't know whats the best way to trigger the updated-process defined in the directive. Can anyone help?

        myApp.controller('KontaktCtrl', function ($scope, $location, CustomerDataService, CaptchaService) {
        $scope.contactRequest = {
            salutation: 'Herr',
            captcha: {
                id: initialCaptchaId
            }
        };
        $scope.errors = {};
    
        $scope.submitAction = function () {
            CustomerDataService.sendRequest($scope.contactRequest).then(function (res) {
                var data = res.data;
                if (res.data.data !== null) { //errors in form. Display them
                    //error handling
                    $scope.reloadCaptcha();
                } else {
                    goToHomeView();
                }
            }, function (error) {
                console.log('An error occurred while updating!', error);
            });
        };
    
    
        var goToHomeView = function () {
            $location.path('/');
        };
    });
    

    Additionally, I have to init the values of select-box and captcha, cause otherwise they are not sent (because the are untouched). Is there any way to avoid this?

    PS: I found a reCAPTCHA directive, but reCAPTCHA is no option due to styling limitations.