Search code examples
pythondjangocaptchatastypie

Django Tastypie Captcha


In Django tastypie, i wrote a login Api as follow:

user = authenticate(username=username, password=password)
if user:
   if user.is_active:
      login(request, user)
      return self.create_response(request, {
            'success': True
            })
   else:
      return self.create_response(request, {
            'success': False,               
            }, HttpForbidden )
else:
   return self.create_response(request, {
         'success': False,
         }, HttpUnauthorized )

i want to set Captcha for this Tasypie Api.

i saw django-simple-captcha, but i found that this module used for Django Forms and Api.

is there any solution for using Captcha with Tastypie Api?!!

Hint: i used Angular.js in ClientSide.


Solution

  • After searching a lot, i found that it doesn't matter you use Tastypie. for Captcha you can use django-simple-captcha.

    At first you just need create a form like this:

    class LoginForm(forms.Form):
        username = forms.CharField()
        password = forms.CharField(widget=forms.PasswordInput)
        captcha_login = CaptchaField()
    

    And then render the template with this object as follow:

    def index(request):       
        return render(request,
                      'shared/layout.html',
                      {'form': LoginForm()})
    

    And finally check captcha in login method:

     def login(self, request, **kwargs):
    
        self.method_check(request, allowed=['post'])
    
        # Validate Captcha on LoginForm.
        form = LoginForm(request.POST)
    
        if form.is_valid() == False:
            return self.create_response(request, {
                   'success': False,
                   'error': form.errors,
                   'new_captcha_key': CaptchaStore.generate_key(),
                   'new_captcha_image': captcha_image_url(CaptchaStore.generate_key()),
                   }, HttpBadRequest)
        else:
            user = authenticate(username=username, password=password)
            if user:
                if user.is_active:
                    login(request, user)
                        return self.create_response(request, {
                               'success': True
                        })
    

    Note: the important thing was Angular config in my case, i add this codes for CSRF protecting :)

    angular.module('myApp').config(function ($interpolateProvider , $routeProvider, $locationProvider, $httpProvider) {
    
      $httpProvider.defaults.xsrfCookieName = 'csrftoken';
      $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
      $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; })
    

    finished !