有人研究过潘多拉是怎么实现获取accesstoken的吗

3.5 4.0的消息传输协议都很简单,arkose也比较容易获取,就是账号密码登录取accesstoken ,协议走不通 用 模拟的方式又慢窗口多的时候又会卡

2 个赞

通过selenium 获取到state 之后 源网站会访问 一个 /p的地址 更新cf cookie ,但是我协议也更新CF COOKIE之后 还是不能Post 一样被403 到底啥情况呀。。

2 个赞

你登录官网 访问 https://chatgpt.com/api/auth/session
就有acctk了
我感觉需要做的就是 绕过cf验证 登录官网即可

2 个赞

我试过本地用 selenium 来模拟点击登录 跳验证出来。

1 个赞

老pandora的auth.py里有完整代码

2 个赞

我指的就是登录呀 session是最后一步

1 个赞

6 我去瞅一眼观摩观摩

1 个赞

auth.py

# -*- coding: utf-8 -*-

import datetime
import json
import re
from datetime import datetime as dt
from urllib.parse import urlparse, parse_qs

import requests
from certifi import where


class Auth0:
    def __init__(self, email: str, password: str, proxy: str = None, use_cache: bool = True, mfa: str = None):
        self.session_token = None
        self.email = email
        self.password = password
        self.use_cache = use_cache
        self.mfa = mfa
        self.session = requests.Session()
        self.req_kwargs = {
            'proxies': {
                'http': proxy,
                'https': proxy,
            } if proxy else None,
            'verify': where(),
            'timeout': 100,
        }
        self.access_token = None
        self.refresh_token = None
        self.expires = None
        self.user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) ' \
                          'Chrome/109.0.0.0 Safari/537.36'

    @staticmethod
    def __check_email(email: str):
        regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
        return re.fullmatch(regex, email)

    def auth(self, login_local=True) -> str:
        if self.use_cache and self.access_token and self.expires and self.expires > dt.now():
            return self.access_token

        if not self.__check_email(self.email) or not self.password:
            raise Exception('invalid email or password.')

        return self.__part_two()

    def get_refresh_token(self):
        return self.refresh_token

    def __part_two(self) -> str:
        code_challenge = 'w6n3Ix420Xhhu-Q5-mOOEyuPZmAsJHUbBpO8Ub7xBCY'
        code_verifier = 'yGrXROHx_VazA0uovsxKfE263LMFcrSrdm4SlC-rob8'
        requests.get("https://ai.fakeopen.com/auth/preauth")
        response = requests.get('https://ai.fakeopen.com/auth/preauth')
        data = json.loads(response.text)
        preauth = data.get('preauth_cookie', None)

        url = 'https://auth0.openai.com/authorize?client_id=pdlLIX2Y72MIl2rhLhTE9VV9bN905kBh&audience=https%3A%2F' \
              '%2Fapi.openai.com%2Fv1&redirect_uri=com.openai.chat%3A%2F%2Fauth0.openai.com%2Fios%2Fcom.openai.chat' \
              '%2Fcallback&scope=openid%20email%20profile%20offline_access%20model.request%20model.read' \
              '%20organization.read%20offline&response_type=code&code_challenge={}' \
              '&code_challenge_method=S256&prompt=login&preauth_cookie={}'.format(code_challenge, preauth)
        return self.__part_three(code_verifier, url)

    def __part_three(self, code_verifier, url: str) -> str:
        headers = {
            'User-Agent': self.user_agent,
            'Referer': 'https://ios.chat.openai.com/',
        }
        resp = self.session.get(url, headers=headers, allow_redirects=True, **self.req_kwargs)

        if resp.status_code == 200:
            try:
                url_params = parse_qs(urlparse(resp.url).query)
                state = url_params['state'][0]
                return self.__part_four(code_verifier, state)
            except IndexError as exc:
                raise Exception('Rate limit hit.') from exc
        else:
            raise Exception('Error request login url.')

    def __part_four(self, code_verifier: str, state: str) -> str:
        url = 'https://auth0.openai.com/u/login/identifier?state=' + state
        headers = {
            'User-Agent': self.user_agent,
            'Referer': url,
            'Origin': 'https://auth0.openai.com',
        }
        data = {
            'state': state,
            'username': self.email,
            'js-available': 'true',
            'webauthn-available': 'true',
            'is-brave': 'false',
            'webauthn-platform-available': 'false',
            'action': 'default',
        }
        resp = self.session.post(url, headers=headers, data=data, allow_redirects=False, **self.req_kwargs)

        if resp.status_code == 302:
            return self.__part_five(code_verifier, state)
        else:
            raise Exception('Error check email.')

    def __part_five(self, code_verifier: str, state: str) -> str:
        url = 'https://auth0.openai.com/u/login/password?state=' + state
        headers = {
            'User-Agent': self.user_agent,
            'Referer': url,
            'Origin': 'https://auth0.openai.com',
        }
        data = {
            'state': state,
            'username': self.email,
            'password': self.password,
            'action': 'default',
        }

        resp = self.session.post(url, headers=headers, data=data, allow_redirects=False, **self.req_kwargs)
        if resp.status_code == 302:
            location = resp.headers['Location']
            if not location.startswith('/authorize/resume?'):
                raise Exception('Login failed.')

            return self.__part_six(code_verifier, location, url)

        if resp.status_code == 400:
            raise Exception('Wrong email or password.')
        else:
            raise Exception('Error login.')

    def __part_six(self, code_verifier: str, location: str, ref: str) -> str:
        url = 'https://auth0.openai.com' + location
        headers = {
            'User-Agent': self.user_agent,
            'Referer': ref,
        }

        resp = self.session.get(url, headers=headers, allow_redirects=False, **self.req_kwargs)
        if resp.status_code == 302:
            location = resp.headers['Location']
            if location.startswith('/u/mfa-otp-challenge?'):
                if not self.mfa:
                    raise Exception('MFA required.')
                return self.__part_seven(code_verifier, location)

            if not location.startswith('com.openai.chat://auth0.openai.com/ios/com.openai.chat/callback?'):
                raise Exception('Login callback failed.')

            return self.get_access_token(code_verifier, resp.headers['Location'])

        raise Exception('Error login.')

    def __part_seven(self, code_verifier: str, location: str) -> str:
        url = 'https://auth0.openai.com' + location
        data = {
            'state': parse_qs(urlparse(url).query)['state'][0],
            'code': self.mfa,
            'action': 'default',
        }
        headers = {
            'User-Agent': self.user_agent,
            'Referer': url,
            'Origin': 'https://auth0.openai.com',
        }

        resp = self.session.post(url, headers=headers, data=data, allow_redirects=False, **self.req_kwargs)
        if resp.status_code == 302:
            location = resp.headers['Location']
            if not location.startswith('/authorize/resume?'):
                raise Exception('MFA failed.')

            return self.__part_six(code_verifier, location, url)

        if resp.status_code == 400:
            raise Exception('Wrong MFA code.')
        else:
            raise Exception('Error login.')

    def get_access_token(self, code_verifier: str, callback_url: str) -> str:
        url_params = parse_qs(urlparse(callback_url).query)

        if 'error' in url_params:
            error = url_params['error'][0]
            error_description = url_params['error_description'][0] if 'error_description' in url_params else ''
            raise Exception('{}: {}'.format(error, error_description))

        if 'code' not in url_params:
            raise Exception('Error get code from callback url.')

        url = 'https://auth0.openai.com/oauth/token'
        headers = {
            'User-Agent': self.user_agent,
        }
        data = {
            'redirect_uri': 'com.openai.chat://auth0.openai.com/ios/com.openai.chat/callback',
            'grant_type': 'authorization_code',
            'client_id': 'pdlLIX2Y72MIl2rhLhTE9VV9bN905kBh',
            'code': url_params['code'][0],
            'code_verifier': code_verifier,
        }
        resp = self.session.post(url, headers=headers, json=data, allow_redirects=False, **self.req_kwargs)

        if resp.status_code == 200:
            json = resp.json()
            if 'access_token' not in json:
                raise Exception('Get access token failed, maybe you need a proxy.')

            if 'refresh_token' in json:
                self.refresh_token = json['refresh_token']

            self.access_token = json['access_token']
            self.expires = dt.utcnow() + datetime.timedelta(seconds=json['expires_in']) - datetime.timedelta(minutes=5)
            return self.access_token
        else:
            raise Exception(resp.text)

4 个赞

:smiley: 谢谢 boss 我回去看看 我之前看老版本文档里写的是要连接 fakeai 呀 ,什么都能取到就是post 数据会被cf 403 无语了

1 个赞

观摩观摩

1 个赞

虽然看不懂但感觉很厉害!

22 个赞

灌水起手势是吧

2 个赞

不错不错,又有作文写了

:rofl: 其实我想知道fk啥原理

水王

1 个赞

我就是通过pandura的auth.py代码去学习怎么写登录 :kissing_smiling_eyes:

生成preauth_cookie有具体的算法吗?接口挂了

取preauth_cookie这个消耗苹果设备呀 :rofl: :rofl:。我现在重新走了一遍官网的登录方式来取,然后简单起了个服务来登录。
就是过cf要手动拿一次,但是一次基本可以用1个多钟。

之前fakeopen的 /auth/preauth接口是怎么拿preauth_cookie的呀,好像啥也没传,直接得到的,有具体的算法吗?

那是调用了始皇的服务,始皇帮你拿了嘛。现在拿不了拉