title: Salesforce Oauth with Django
body: <p>I am an advanced beginner and I have been stuck on this issue for a couple of days now.  The app I am creating requires access to each user's Salesforce account.  In order to make an API connection, we need to store their Salesforce username, password and access token.  </p>
  
  <p>The user will provide their Salesforce username and password then click a button to Authorize.  This button directs the user to:</p>
  
  <p><a href="https://login.salesforce.com/services/oauth2/authorize?response_type=code&amp;client_id=dsf3434&amp;redirect_uri=https%3A%2F%2Fwww.mysite.com/oauth/salesforce/&amp;display=popup" rel="nofollow">https://login.salesforce.com/services/oauth2/authorize?response_type=code&amp;client_id=dsf3434&amp;redirect_uri=https%3A%2F%2Fwww.mysite.com/oauth/salesforce/&amp;display=popup</a></p>
  
  <p>The response from Salesforce Oauth servers should be:</p>
  
  <pre><code>https://www.mysite.com/oauth/salesforce/?display=popup&amp;code=aPrx6RMKPrMpm.SHNCxBmHz3ZiHMc.xZRY9RHLekkzW_G8Uu.KyqmmY0.JGCr5roqPT49vTCbg%3D%3D
  </code></pre>
  
  <p>Here is the <strong>views.py</strong> file</p>
  
  <pre><code>from django.views.generic.base import RedirectView, TemplateView, View
  from django.http import Http404, HttpResponse
  from django.conf import settings
  from django.contrib import messages
  from django.core.urlresolvers import reverse_lazy, reverse
  from guardian.mixins import LoginRequiredMixin
  from simple_salesforce import Salesforce
  import logging
  
  from campaigns.views import CampaignOwnerPermission
  from . import api, utils, settings
  from .models import OauthToken
  
  
  class SalesforceOauthRedirectView(
      LoginRequiredMixin,
      RedirectView
  ):
  
      def get_redirect_url(self):
          logger = logging.getLogger(__name__)
  
          # Extract 'code' parameter from return URL and set to variable
          if (
              not self.request.GET.get(
                  'code', None
              ) is None
          ):
              try:
                  existing_credentials = OauthToken.objects.get(
                      user=request.user
                      )
                  # get stored Salesforce username and password
                  username = str(existing_credentials.salesforce_user_id)
                  password = str(existing_credentials.password)
                  payload = {
                      'grant_type': 'password',
                      'client_id': str(settings.CONSUMER_KEY),
                      'client_secret': str(settings.CONSUMER_SECRET),
                      'username': username,
                      # must concatenate password &amp; code before passing to server
                      'password': password + str(code)
                      }
  
                  try:
                      # Post payload to Salesforce Oauth server and get user
                      # token in response.
                      r = requests.post(
                          "https://login.salesforce.com/services/oauth2/token",
                          headers={
                              "Content-Type":"application/x-www-form-urlencoded"
                          },
                              data=payload
                      )
  
                      # Decode the JSON response from Salesforce Oauth server
                      decoded = json.loads(r.content)
                      # Store access_token to database
                      existing_credentials.token = decoded['access_token']
                      existing_credentials.active = True
                      existing_credentials.save()
  
                      messages.add_message(
                          self.request,
                          messages.SUCCESS,
                          _(
                              'Successfully updated Salesforce  \
                              authentication with user credentials: "%s"'
                              %
                              salesforce_user_id
                          )
                      )
                      # Success point
                      return reverse_lazy('providers:provider_list')
  
                      # except (ValueError, KeyError, TypeError):
                      # logger.error('Could not decode response from Salesforce API')
  
                      # Not sure how this should be arranged
                  except:
                      logger.error(
                          'Could not get Oauth_token from Salesforce API.'
                          )
                      messages.add_message(
                          self.request,
                          messages.WARNING,
                              ('Could not get Oauth_token from Salesforce API.\n\n \
                              Salesforce may be experiencing an outage.  Try again \
                              in a few minutes and contact explorro support if the \
                              problem persists.'
                              )
                      )
                      return reverse_lazy('providers:provider_list')
  
  
              except:
                  logger.error('Could not get users Salesforce credentials')
                  messages.add_message(
                      self.request,
                      messages.WARNING,
                      ('There was a problem authenticating with \
                       Salesforce.  Be sure to enter your Salesforce \
                       username and password before attempting to authorize your\
                       account.  Contact our support team if you need some help.'
                       )
                  )
                  return reverse_lazy('providers:provider_list')
  
          else:
              pass
              return reverse_lazy('providers:provider_list')
              messages.add_message(
                  self.request,
                  messages.WARNING,
                  ('Could not retrieve Salesforce Authorization Code\n\n \
                   Contact your Salesforce administrator for assistance.'
                  )
              )
  </code></pre>
  
  <p>The 'code' parameter (example value = randomTextCode) is parsed from the response URL, and passed as part of the 'payload' variable (line 38) to <a href="https://login.salesforce.com/services/oauth2/token" rel="nofollow">https://login.salesforce.com/services/oauth2/token</a></p>
  
  <p>The last step <em>should be</em> receiving a JSON response from <a href="https://login.salesforce.com/services/oauth2/token" rel="nofollow">https://login.salesforce.com/services/oauth2/token</a> which contains the access_token</p>
  
  <p>The error seems to be originating from the first try/except statement, as I am getting the exception error message on lines #103-106.  </p>
  
  <p>While running locally, here is the server response (301)</p>
  
  <pre><code>"GET /oauth/salesforce/?display=popup&amp;code=aPrx6RMKPrMpm.SHNCxBmHz3ZgWIqBWQKmln4Q6TfdI8TbmeWuMw5H..Di.342no15VYNvmgzA%3D%3D HTTP/1.1" 301 0
  </code></pre>
  
  <p>Here is <strong>models.py</strong></p>
  
  <pre><code>from django.db import models
  from django.conf import settings
  from django.utils.translation import ugettext_lazy as _
  
  
  class OauthToken(models.Model):
      user = models.ForeignKey(
          settings.AUTH_USER_MODEL,
          related_name='Salesforce User',
          verbose_name=_('Salesforce User'),
          db_index=True,
      )
      salesforce_user_id = models.EmailField(
          verbose_name=_('Salesforce user id'),
          db_index=True, unique=True
      )
      password = models.CharField(    # TODO: This needs to be encrypted!!
          verbose_name=_('Salesforce password'),
          max_length=256,
      )
      token = models.CharField(
          verbose_name=_('Token'),
          max_length=256,
          null=True,
          blank=True,
      )
      security_token = models.CharField(
          verbose_name=_('Security Token'),
          max_length=256
      )
      active = models.BooleanField(
          verbose_name=_('Active'),
          default=False,
          db_index=True
      )
  
      def __unicode__(self):
          return str(self.salesforce_user_id)
  
      class Meta:
          verbose_name = _('Oauth token')
          verbose_name_plural = _('Oauth tokens')
  </code></pre>
  
  <p>Any help troubleshooting this issue is greatly appreciated.</p>