title: django-allauth logging in with Facebook token from iOS Device
body: <p>I am using the Facebook iOS SDK to POST the Facebook Access Token to my Django server URI. The corresponding views.py function is shown below and I get a 200 Response code when I do the POST from iOS. However, I have a second @login_required decorated URI that I call from the iOS Device immediately afterword which considers me not logged in and redirects me to my main page. What am I doing wrong? How do I 'stay' logged in after my successful POST from iOS?</p>
  
  <pre><code># For POSTing the facebook token
  from django.views.decorators.csrf import csrf_exempt
  from allauth.socialaccount import providers
  from allauth.socialaccount.models import SocialLogin, SocialToken, SocialApp
  from allauth.socialaccount.providers.facebook.views import fb_complete_login
  from allauth.socialaccount.helpers import complete_social_login
  
  # Log in from Facebook
  @csrf_exempt
  def mobile_facebook_login(request):
      response = HttpResponse() ## Create an HTTP Response Object
      if request.method == "POST": # The method better be a POST
          access_token = request.POST.get('access_token') # Get token   
          try:
              app = SocialApp.objects.get(provider="facebook")
              token = SocialToken(app=app, token=access_token)
  
              # Check token against facebook                  
              login = fb_complete_login(request, app, token)
              login.token = token
              login.state = SocialLogin.state_from_request(request)
  
              # Add or update the user into users table
              ret = complete_social_login(request, login)
  
              # If we get here we've succeeded
              response['Auth-Response'] = 'success'
              response.status_code = 200 # Set status  
              return response   
          except Exception,e:
              # If we get here we've failed
              response['Auth-Response'] = 'failure: %s'%(e)
              response.status_code = 401 # Set status
              return response
      else:
          # If we get here we've failed
          response['Auth-Response'] = 'failure'
          response.status_code = 401 # Set status
          return response
  </code></pre>
  
  <p>======= UPDATE ==========</p>
  
  <p>Ok, thanks for the comments. So I am now POSTing the facebook email address as well and getting the user and logging them in manually. However, subsequent requests STILL are not authenticated. So the @login_required decorator still fails.. Any other ideas?</p>
  
  <pre><code># Log in from Facebook
  @csrf_exempt
  def mobile_facebook_login(request):
      response = HttpResponse() ## Create an HTTP Response Object
      if request.method == "POST": # The method better be a POST
          access_token = request.POST.get('access_token') # Get token
          email = request.POST.get('email') # Get email
          try:
              app = SocialApp.objects.get(provider="facebook")
              token = SocialToken(app=app, token=access_token)
  
              # Check token against facebook                  
              login = fb_complete_login(request, app, token)
              login.token = token
              login.state = SocialLogin.state_from_request(request)
  
              # Add or update the user into users table
              ret = complete_social_login(request, login)
  
              # Try to get username from email
              try:
                          user = User.objects.get(email=email) # Get User
                  # Login the user from Django's perspective
                  user.backend = 'django.contrib.auth.backends.ModelBackend'
                  auth_login(request,user)
                  except User.DoesNotExist:
                          # If we get here we've failed
                  response['Auth-Response'] = 'failure: %s'%(e)
                  response.status_code = 401 # Set status
                  return response
  
              # If we get here we've succeeded
              response['Auth-Response'] = 'success'
              response.status_code = 200 # Set status  
              return response   
          except Exception,e:
              # If we get here we've failed
              response['Auth-Response'] = 'failure: %s'%(e)
              response.status_code = 401 # Set status
              return response
      else:
          # If we get here we've failed
          response['Auth-Response'] = 'failure'
          response.status_code = 401 # Set status
          return response
  </code></pre>
  
  <p>==== Another Update ==========</p>
  
  <p>Based on the 2nd answer in this post:
  <a href="https://stackoverflow.com/questions/6560182/django-authentication-without-a-password">django authentication without a password</a></p>
  
  <p>I created a custom login backend that does not require a password. The 3rd answer in that post discusses how doing this:</p>
  
  <pre><code>user.backend = 'django.contrib.auth.backends.ModelBackend'
  login(request, user)
  </code></pre>
  
  <p>Doesn't store the login validation in the session. So I tried using a custom backend.</p>
  
  <p>Here is my modified code:</p>
  
  <pre><code># Log in from Facebook
  @csrf_exempt
  def mobile_facebook_login(request):
      response = HttpResponse() ## Create an HTTP Response Object
      if request.method == "POST": # The method better be a POST
          access_token = request.POST.get('access_token') # Get token
          email = request.POST.get('email') # Get email
          try:
              app = SocialApp.objects.get(provider="facebook")
              token = SocialToken(app=app, token=access_token)
  
              # Check token against facebook                  
              login = fb_complete_login(request, app, token)
              login.token = token
              login.state = SocialLogin.state_from_request(request)
  
              # Add or update the user into users table
              ret = complete_social_login(request, login)
  
              # Try to get username from email
              try:
                          user = User.objects.get(email=email) # Get User
                  # Login the user from Django's perspective
                  user.backend = 'django_tours.auth_backend.PasswordlessAuthBackend'
                  user = authenticate(email=user.email)
                  auth_login(request,user)
                  #request.session.cycle_key()
                      except User.DoesNotExist:
                          # If we get here we've failed
                  response['Auth-Response'] = 'failure: %s'%(e)
                  response.status_code = 401 # Set status
                  return response
  
              # If we get here we've succeeded
              response['Auth-Response'] = 'success'
              response['User-Is-Authenticated'] = '%s'%(request.user.is_authenticated())
              response.status_code = 200 # Set status  
              return response   
          except Exception,e:
              # If we get here we've failed
              response['Auth-Response'] = 'failure: %s'%(e)
              response.status_code = 401 # Set status
              return response
      else:
          # If we get here we've failed
          response['Auth-Response'] = 'failure'
          response.status_code = 401 # Set status
          return response
  </code></pre>
  
  <p>Using hurl.it I get this HTTP 200 response, but am still NOT considered logged in from the iPhone:</p>
  
  <pre><code>Auth-Response: success
  Content-Encoding: gzip
  Content-Length: 20
  Content-Type: text/html; charset=utf-8
  Date: Thu, 08 May 2014 00:22:47 GMT
  Server: Apache/2.2.22 (Ubuntu)
  Set-Cookie: csrftoken=UuJDP6OB3YCSDtXLEa10MgJ70tDtIfZX; expires=Thu, 07-May-2015 00:22:48 GMT; Max-Age=31449600; Path=/, sessionid=kdr061v1pcsbqtvgsn3pyyqj9237z6k8; expires=Thu, 22-May-2014 00:22:48 GMT; httponly; Max-Age=1209600; Path=/, messages="4f919699a4730a3df220a0eb3799ed59d2756825$[[\"__json_message\"\0540\05425\054\"Successfully signed in as philbot.\"]]"; Path=/
  User-Is-Authenticated: True
  Vary: Cookie,Accept-Encoding
  </code></pre>