Guest User

Untitled

a guest
Mar 7th, 2023
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.50 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. from argparse import ArgumentParser
  4. from base64 import urlsafe_b64encode
  5. from hashlib import sha256
  6. from pprint import pprint
  7. from secrets import token_urlsafe
  8. from sys import exit
  9. from urllib.parse import urlencode
  10. from webbrowser import open as open_url
  11.  
  12. import requests
  13.  
  14. # Latest app version can be found using GET /v1/application-info/android
  15. USER_AGENT = "PixivAndroidApp/5.0.234 (Android 11; Pixel 5)"
  16. REDIRECT_URI = "https://app-api.pixiv.net/web/v1/users/auth/pixiv/callback"
  17. LOGIN_URL = "https://app-api.pixiv.net/web/v1/login"
  18. AUTH_TOKEN_URL = "https://oauth.secure.pixiv.net/auth/token"
  19. CLIENT_ID = "MOBrBDS8blbauoSck0ZfDbtuzpyT"
  20. CLIENT_SECRET = "lsACyCD94FhDUtGTXi3QzcFE2uU1hqtDaKeqrdwj"
  21.  
  22.  
  23. def s256(data):
  24.     """S256 transformation method."""
  25.  
  26.     return urlsafe_b64encode(sha256(data).digest()).rstrip(b"=").decode("ascii")
  27.  
  28.  
  29. def oauth_pkce(transform):
  30.     """Proof Key for Code Exchange by OAuth Public Clients (RFC7636)."""
  31.  
  32.     code_verifier = token_urlsafe(32)
  33.     code_challenge = transform(code_verifier.encode("ascii"))
  34.  
  35.     return code_verifier, code_challenge
  36.  
  37.  
  38. def print_auth_token_response(response):
  39.     data = response.json()
  40.  
  41.     try:
  42.         access_token = data["access_token"]
  43.         refresh_token = data["refresh_token"]
  44.     except KeyError:
  45.         print("error:")
  46.         pprint(data)
  47.         exit(1)
  48.  
  49.     accessTokenFile = open("access_token.txt", "w")
  50.     refreshTokenFile = open("refresh_token.txt", "w")
  51.     accessTokenFile.write(access_token)
  52.     refreshTokenFile.write(refresh_token)
  53.     # print("access_token:", access_token)
  54.     # print("refresh_token:", refresh_token)
  55.     # print("expires_in:", data.get("expires_in", 0))
  56.  
  57.  
  58. def login():
  59.     code_verifier, code_challenge = oauth_pkce(s256)
  60.     login_params = {
  61.         "code_challenge": code_challenge,
  62.         "code_challenge_method": "S256",
  63.         "client": "pixiv-android",
  64.     }
  65.  
  66.     open_url(f"{LOGIN_URL}?{urlencode(login_params)}")
  67.  
  68.     try:
  69.         code = input("code (network tab -> search callback?): ").strip()
  70.     except (EOFError, KeyboardInterrupt):
  71.         return
  72.  
  73.     response = requests.post(
  74.         AUTH_TOKEN_URL,
  75.         data={
  76.             "client_id": CLIENT_ID,
  77.             "client_secret": CLIENT_SECRET,
  78.             "code": code,
  79.             "code_verifier": code_verifier,
  80.             "grant_type": "authorization_code",
  81.             "include_policy": "true",
  82.             "redirect_uri": REDIRECT_URI,
  83.         },
  84.         headers={"User-Agent": USER_AGENT},
  85.     )
  86.     print_auth_token_response(response)
  87.  
  88.  
  89. def refresh(refresh_token):
  90.     response = requests.post(
  91.         AUTH_TOKEN_URL,
  92.         data={
  93.             "client_id": CLIENT_ID,
  94.             "client_secret": CLIENT_SECRET,
  95.             "grant_type": "refresh_token",
  96.             "include_policy": "true",
  97.             "refresh_token": refresh_token,
  98.         },
  99.         headers={"User-Agent": USER_AGENT},
  100.     )
  101.     print_auth_token_response(response)
  102.  
  103.  
  104. def main():
  105.     parser = ArgumentParser()
  106.     subparsers = parser.add_subparsers()
  107.     parser.set_defaults(func=lambda _: parser.print_usage())
  108.     login_parser = subparsers.add_parser("login")
  109.     login_parser.set_defaults(func=lambda _: login())
  110.     refresh_parser = subparsers.add_parser("refresh")
  111.     refresh_parser.add_argument("refresh_token")
  112.     refresh_parser.set_defaults(func=lambda ns: refresh(ns.refresh_token))
  113.     args = parser.parse_args()
  114.     args.func(args)
  115.  
  116.  
  117. if __name__ == "__main__":
  118.     main()
  119.  
Add Comment
Please, Sign In to add comment