title: 401: Authorization Required when retrieving Request Token from Twitter API
body: <p>I'm working on a Django application which retrieves some data from Twitter, and I need to work with requests manually since it's for an exam whose main focus is for us to learn how to work with network protocols such as HTTP. So please don't suggest me to use a wrapper.</p>
  
  <p>My issue is that whenever I try to request the initial request token (with a POST request that is referenced in this <a href="https://dev.twitter.com/web/sign-in/implementing" rel="nofollow noreferrer">doc</a> and also <a href="https://developer.twitter.com/en/docs/basics/authentication/api-reference/request_token" rel="nofollow noreferrer">here</a>), I receive  a 401: Authorization Required and I have no clue what could be causing it, since I'm including the Authorization header in exactly the format required by the docs I've linked. It may be that while working with <code>urllib</code> I don't manage to make the POST request as I wanted, or perhaps there's something wrongin how I made the signature/where I've placed it in the header, even though in my opinion it should be alright. </p>
  
  <p>Here's my code to handle the request to "sign in with Twitter":</p>
  
  <pre><code>def sign(request):
      url = 'https://api.twitter.com/oauth/request_token'
      #I store consumer key, consumer secret and callback url in a txt
      dir_path = path.dirname(path.realpath(__file__))
      with open(path.join(dir_path, 'credentials.txt'), 'r') as TweetCred:
          creds = TweetCred.read().split(linesep)
      oauth_consumer_key = creds[0].split()[1]
      oauth_callback = creds[1].split()[1]
      consumer_secret = creds[2].split()[1]
  
      oauth_nonce = ''.join(SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(32))
      #Desperate to understand what could be causing the error, I tried to use an integer timestamp sinceit was integer in the examples
      oauth_timestamp = int(time.time())
      parameter_string =  (   'oauth_nonce=' + urllib.parse.quote(oauth_nonce, safe='') +
                              '&amp;oauth_callback=' + urllib.parse.quote(oauth_callback, safe='') + 
                              '&amp;oauth_signature_method=' + urllib.parse.quote('HMAC-SHA1', safe='') +
                              '&amp;oauth_timestamp=' + urllib.parse.quote(str(oauth_timestamp), safe='') +
                              '&amp;oauth_consumer_key=' + urllib.parse.quote(oauth_consumer_key, safe='') +
                              '&amp;oauth_version=' + urllib.parse.quote('1.0', safe='')
                          )
  
      sigbase = 'POST' + '&amp;' + urllib.parse.quote(url, safe='') + '&amp;' + urllib.parse.quote(parameter_string, safe='')
      signkey = urllib.parse.quote(consumer_secret, safe='') + '&amp;'
  
      key = bytes(signkey, 'UTF-8')
      base = bytes(sigbase, 'UTF-8')
      digester = hmac.new(key, base, hashlib.sha1)
      binsignature = digester.digest()
      signature = urllib.parse.quote(base64.urlsafe_b64encode(binsignature), safe='')    
      oauth_header =  ('Oauth ' + 'oauth_nonce="%s", ' % urllib.parse.quote(oauth_nonce, safe='') + 
                                  'oauth_callback="%s", ' % urllib.parse.quote(oauth_callback, safe='') +
                                  'oauth_signature_method="%s", ' % urllib.parse.quote('HMAC-SHA1', safe='') +
                                  'oauth_timestamp="%s", ' %urllib.parse.quote(str(oauth_timestamp), safe='')  +
                                  'oauth_consumer_key="%s", ' % urllib.parse.quote(oauth_consumer_key, safe='') +
                                  'oauth_version="%s", ' % urllib.parse.quote('1.0', safe='') +
                                  'oauth_signature="%s"' % signature
                      )
      headers = {'Authorization': oauth_header}
      #urllib wants a body to know that it's a POST, at least that's what the docs said, so I'm providing an empty one
      values = {}
      data = urllib.parse.urlencode(values).encode('ascii')
      TokenRequest = urllib.request.Request(url, data, headers)
      try:
          print('opening request token url...')
          with urllib.request.urlopen(TokenRequest) as response:
              if response.getcode() != 200:
                  print('Response is %s' % response.getcode())
                  return HttpResponse('Error in getting the token from Twitter, please try again...')
              body = loads(response.read())
              if body['oauth_callback_confirmed'] != 'true':
                  print('oauth_callback not confirmed')
                  return HttpResponse('Error in getting the token from Twitter, please try again...')
              oauth_token = body['oauth_token']
              oauth_token_secret = body['oauth_token_secret']
      except urllib.error.HTTPError as err:
          #my program always ends up here, catches the exception and returns the line below
          return HttpResponse('Error %s in getting the token from Twitter, please try again...' % err)
  
      print('Successfully retrieved request token! Redirecting...')
      loggee = User.objects.Create()
      loggee.oauth_token = oauth_token
      loggee.oauth_token_secret = oauth_token_secret
      return HttpResponseRedirect('https://api.twitter.com/oauth/authenticate?oauth_token='+oauth_token)
  </code></pre>
  
  <p>Any help will be appreciated! I'm quite in a hurry and I really can't wrap my head around this!</p>