Get HTTP 400 Bad Request when login using Python requests
<p>I'm trying to use <code>requests</code> to log into <a href="https://appleid.apple.com/cn" rel="nofollow">https://appleid.apple.com/cn</a> (/us should be the same, but get 400 Bad request returned.</p>

<pre><code>session = requests.Session()

productURL = &lt;the URL above&gt;

headers = {
            "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
            "Accept-Encoding": "gzip, deflate, sdch, br",
            "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.6,en;q=0.4",
            "Upgrade-Insecure-Requests":"1",
            "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/52.0.2743.116 Chrome/52.0.2743.116 Safari/537.36"
        }
session.headers = headers
r = session.get(productURL)

url = "//idmsa.apple.com/appleauth/auth/signin?widgetKey=af1139274f266b22b68c2a3e7ad932cb3c0bbe854e13a79af78dcc73136882c3&amp;language=zh_CN&amp;rv=1"
r = session.get(url)

url = "//idmsa.apple.com/appleauth/auth/signin"
headers = {
        "Accept":"application/json, text/javascript, */*; q=0.01",
        "Accept-Encoding":"gzip, deflate, br",
        "Accept-Language":"zh-CN,zh;q=0.8,zh-TW;q=0.6,en;q=0.4",
        "Connection":"keep-alive",
        "Content-Length":"77",
        "Content-Type":"application/json",
        "Host":"idmsa.apple.com",
        "Origin":"https://idmsa.apple.com",
        "Referer":"//idmsa.apple.com/appleauth/auth/signin?widgetKey=af1139274f266b22b68c2a3e7ad932cb3c0bbe854e13a79af78dcc73136882c3&amp;language=zh_CN&amp;rv=1",
        "User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/52.0.2743.116 Chrome/52.0.2743.116 Safari/537.36",
        "X-Apple-Domain-Id":1,
        "X-Apple-I-FD-Client-Info":{"U":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/52.0.2743.116 Chrome/52.0.2743.116 Safari/537.36","L":"en-US","Z":"GMT+08:00","V":"1.1","F":"7da44j1e3NlY5BSo9z4ofjb75PaK4Vpjt4U_98uszHVyVxFAk.lzXJJIneGffLMC7EZ3QHPBirTYKUowRslz8eibjVdxljQlpQJuYY9hte_1an92r5xj6KksmfTPdFdgmVxf7_OLgiPFMJhHFW_jftckkCoqAkCoq4ly_0x0uVMV0jftckcKyAd65hz7fwdGEM6uJ6o6e0T.5EwHXXTSHCSPmtd0wVYPIG_qvoPfybYb5EtCKoxw4EiCvTDfPbJROKjCJcJqOFTsrhsui65KQnK94CaJ6hO3f9p_nH1zDz.ICMpwoNSdqdbAE9XXTneNufuyPBDjaY2ftckuyPB884akHGOg429OMNo71xFmrur.S9RdPQSzOy_Aw7UTlf_0pNA1OXu_Llri5Ly.EKY.6ekL3sdmX.Cr_Jz9KyFxv5icCmVug4WBkl1BQLz4mvmfTT9oaSumKkpjlRiwerbXh8bUu_LzQW5BNv_.BNlYCa1nkBMfs.Byn"},
        "X-Apple-Locale":"zh_CN",
        "X-Apple-Widget-Key":"af1139274f266b22b68c2a3e7ad932cb3c0bbe854e13a79af78dcc73136882c3",
        "X-Requested-With":"XMLHttpRequest"
        }
session.headers = headers

payload = {
            "accountName" : "accountName",
            "password" : "password",
            "rememberMe" : False
        }
r = session.post(url, params=payload)
</code></pre>

<h3>Headers info</h3>

request headers

<pre><code>{
  'Content-Length': '77',
  'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.6,en;q=0.4',
  'Accept-Encoding': 'gzip, deflate, br',
  'X-Apple-I-FD-Client-Info': {
    'F': '7da44j1e3NlY5BSo9z4ofjb75PaK4Vpjt4U_98uszHVyVxFAk.lzXJJIneGffLMC7EZ3QHPBirTYKUowRslz8eibjVdxljQlpQJuYY9hte_1an92r5xj6KksmfTPdFdgmVxf7_OLgiPFMJhHFW_jftckkCoqAkCoq4ly_0x0uVMV0jftckcKyAd65hz7fwdGEM6uJ6o6e0T.5EwHXXTSHCSPmtd0wVYPIG_qvoPfybYb5EtCKoxw4EiCvTDfPbJROKjCJcJqOFTsrhsui65KQnK94CaJ6hO3f9p_nH1zDz.ICMpwoNSdqdbAE9XXTneNufuyPBDjaY2ftckuyPB884akHGOg429OMNo71xFmrur.S9RdPQSzOy_Aw7UTlf_0pNA1OXu_Llri5Ly.EKY.6ekL3sdmX.Cr_Jz9KyFxv5icCmVug4WBkl1BQLz4mvmfTT9oaSumKkpjlRiwerbXh8bUu_LzQW5BNv_.BNlYCa1nkBMfs.Byn',
    'Z': 'GMT+08:00',
    'U': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/52.0.2743.116 Chrome/52.0.2743.116 Safari/537.36',
    'L': 'en-US',
    'V': '1.1',
  },
  'Connection': 'keep-alive',
  'X-Apple-Widget-Key': 'af1139274f266b22b68c2a3e7ad932cb3c0bbe854e13a79af78dcc73136882c3',
  'Origin': '//idmsa.apple.com',
  'Accept': 'application/json, text/javascript, */*; q=0.01',
  'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/52.0.2743.116 Chrome/52.0.2743.116 Safari/537.36',
  'Host': 'idmsa.apple.com',
  'X-Apple-Domain-Id': 1,
  'Referer': '//idmsa.apple.com/appleauth/auth/signin?widgetKey=af1139274f266b22b68c2a3e7ad932cb3c0bbe854e13a79af78dcc73136882c3&amp;language=zh_CN&amp;rv=1',
  'X-Apple-Locale': 'zh_CN',
  'X-Requested-With': 'XMLHttpRequest',
  'Content-Type': 'application/json',
}
</code></pre>

response headers

<pre><code>{
  'X-XSS-Protection': '1; mode=block',
  'X-Content-Type-Options': 'nosniff',
  'Content-Security-Policy': "default-src *; object-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.apple.com https://*.cdn-apple.com; style-src 'unsafe-inline' https://*.apple.com https://*.cdn-apple.com; connect-src 'self'; img-src 'self' data: https://*.apple.com https://*.cdn-apple.com https://*.icloud.com https://*.mzstatic.com; media-src * data:;",
  'Content-Encoding': 'gzip',
  'Transfer-Encoding': 'chunked',
  'Set-Cookie': 'dslang=CN-ZH; Domain=.apple.com; Path=/; Secure; HttpOnly, site=CHN; Domain=.apple.com; Path=/; Secure; HttpOnly',
  'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
  'Vary': 'Accept-Encoding',
  'Expires': 'Thu, 01 Jan 1970 00:00:00 GMT',
  'Server': 'Apple',
  'Connection': 'close',
  'X-BuildVersion': 'R15',
  'Pragma': 'no-cache',
  'Cache-Control': 'no-cache, no-store',
  'Date': 'Sat, 01 Oct 2016 04:23:19 GMT',
  'X-FRAME-OPTIONS': 'DENY',
}
</code></pre>

<p>I checked all the headers field with the real request headers, "X-Apple-I-FD-Client-Info" is the only one not correct. Dig a little bit, it was calculated by javascript. 'Z','U','L','V' are constant, depends on you browser info and timezone etc. But the 'F' is a very long random string</p>

<ul>
<li>Is "X-Apple-I-FD-Client-Info" the problem result in 400 Bad request?</li>
<li>Is this the right way to write something like auto login? By compareing request headers and cookies one by one?</li>
<li>Is it possible to generate or skip header "X-Apple-I-FD-Client-Info"?</li>
<li>How can I get this auto login work?</li>
</ul>

<p>Since I'm new and can't comment (I don't quite understand the reputation system yet), I'll have to write an answer. </p>

<p>I know that Google recently blocked the login via scripts (well, via most scripts) because it was rather easy to conduct brute force attacks against accounts. </p>

<p>I am presuming that Apple did something very similar and thus making it hard to log onto the AppleId. Do you know for sure that it is possible to login that way?</p>

<p>Greetings,
Narusan</p>

python