是不是可以实现一个油猴脚本,通过refresh token获取access token实现 new.oaifree.com 的自动登录

我咋记得有人搞过

后面我搞搞access token的自动登录?现在可以先用share token的 https://tokens.jerryz.com.cn/share/your_id

这个咋用,your_id填啥

你到 tokens.jerryz.com.cn 中填入rt就可以得到八位id

始皇的new站可以直接用share token登录吧?我也没有自测过

或许可以通过share token实现?
rt → at → st

# rt 换  at
curl -X POST https://token.oaifree.com/api/auth/refresh \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "refresh_token=xxxxx"

# at 生成 st
curl 'https://chat.oaifree.com/token/register' \
  -H 'content-type: application/x-www-form-urlencoded; charset=UTF-8' \
  --data-raw "unique_name=$(openssl rand -hex 8)" \
  --data-raw 'access_token=xxxxx' \
  --data-raw 'expires_in=0' \
  --data-raw 'site_limit=' \
  --data-raw 'gpt35_limit=-1' \
  --data-raw 'gpt4_limit=-1' \
  --data-raw 'show_conversations=true'


# st 登录
https://new.oaifree.com/auth/login_share?token=fk-xxxx

更新可以通过st返回的时间错 expire_at 判断

1 个赞

不错 不错

在chatgpt的帮助下写了个勉强能用的,不过明天才有rt,还没测试,只测试了自动填入at,没啥问题。

使用方法:在源代码里填好自己的refresh token,访问 new.oaifree.com,如果处于未登录状态则会自动登录。

// @name         oaifree自动登录
// @namespace    https://linux.do/u/yeahow/
// @version      1.0
// @description  通过refresh token获取access token后自动填入并登录new.oaifree.com
// @author       yeahow
// @match        https://new.oaifree.com/auth/login_auth0
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // 预先设置好的refreshToken
    var refreshToken = 'your-refresh-token-here';
    var accessToken = '';

    // 立即获取accessToken
    (async function fetchAccessToken() {
        const response = await fetch('https://token.oaifree.com/api/auth/refresh', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
            },
            body: `refresh_token=${encodeURIComponent(refreshToken)}`
        });
        const data = await response.json();
        accessToken = data.access_token;

        // 页面加载完成后执行
        window.addEventListener('load', function() {
            clickContinueButton();
            waitForSwal();
        });
    })();

    // 自动点击 "Continue with Access Token" 按钮
/*    function clickContinueButton0() {
        var continueButton = document.querySelector('#submit-token');
        if (continueButton) {
            continueButton.click();
        }
    }*/

    // 修改后的 clickContinueButton 函数
function clickContinueButton() {
    var continueButton = document.querySelector('#submit-token');
    if (continueButton) {
        continueButton.click();
        setTimeout(fillAccessToken, 300);  // 增加一个300毫秒的延迟,等待方框完全加载出来
    }
}


    // 填入accessToken并点击OK
    function fillAccessToken() {
        var inputField = document.querySelector('.swal2-textarea');
        var okButton = document.querySelector('.swal2-confirm');

        if (inputField && okButton) {
            inputField.value = accessToken;
            okButton.click();
        }
    }

    // 等待Swal弹窗出现并填入token
    function waitForSwal() {
        var observer = new MutationObserver(function(mutations) {
            mutations.forEach(function(mutation) {
                if (mutation.addedNodes.length) {
                    fillAccessToken();
                    observer.disconnect();  // 一旦找到,停止观察
                }
            });
        });

        observer.observe(document.body, { childList: true, subtree: true });
    }

})();

第一次写脚本,写的很烂轻喷,本来也是写着自己用的()

1 个赞

人工智能软件开发

软件开发人工智能

人工智能软件开发

我也用gpt简单糊了一个 :grinning: :grinning:

// ==UserScript==
// @name         OAIFree Auto Login
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  自动判断st是否过期,如果过期则重新获取,并自动跳转登陆,同时在控制台打印日志输出
// @author       You
// @match        https://new.oaifree.com/auth/login_auth0
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @connect      token.oaifree.com
// @connect      chat.oaifree.com
// ==/UserScript==

(function() {
    'use strict';

    const refreshToken = 'xxxxxx';  // 替换为你的 refresh token

    // 获取当前时间戳
    function getCurrentTimestamp() {
        return Math.floor(Date.now() / 1000);
    }

    // 检查 st 是否过期
    function isSTExpired() {
        const expireAt = GM_getValue('expire_at', 0);
        console.log("st expire at: "+ expireAt )
        return isNaN(expireAt) || getCurrentTimestamp() >= expireAt;
    }

    // 使用 rt 换取 at
    function getAccessToken(refreshToken) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'POST',
                url: 'https://token.oaifree.com/api/auth/refresh',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                data: `refresh_token=${refreshToken}`,
                onload: function(response) {
                    if (response.status === 200) {
                        const data = JSON.parse(response.responseText);
                        if(data.access_token){
                            resolve(data.access_token)
                        }else{
                            reject('Failed to generate access token, response: ' + data);
                        }
                    } else {
                        reject('Failed to refresh access token');
                    }
                },
                onerror: function(e) {
                    console.error(e)
                    reject('Failed to refresh access token');
                }
            });
        });
    }

    // 使用 at 生成 st
    function getShareToken(accessToken) {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'POST',
                url: 'https://chat.oaifree.com/token/register',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
                },
                data: `unique_name=${generateRandomHex(8)}&access_token=${accessToken}&expires_in=0&site_limit=&gpt35_limit=-1&gpt4_limit=-1&show_conversations=true`,
                onload: function(response) {
                    if (response.status === 200) {
                        const data = JSON.parse(response.responseText);
                        GM_setValue('expire_at', data.expire_at);
                        if(data.token_key){
                            resolve(data.token_key)
                        }else{
                            reject('Failed to generate share token, response: ' + data);
                        }
                    } else {
                        reject('Failed to generate share token');
                    }
                },
                onerror: function(e) {
                    console.error(e)
                    reject('Failed to generate share token');
                }
            });
        });
    }

    // 生成随机字符串
    function generateRandomHex(length) {
        let result = '';
        const characters = '0123456789abcdef';
        const charactersLength = characters.length;
        for (let i = 0; i < length; i++) {
            result += characters.charAt(Math.floor(Math.random() * charactersLength));
        }
        return result;
    }

    // 自动登录
    function autoLogin(shareToken) {
        const loginUrl = `https://new.oaifree.com/auth/login_share?token=${shareToken}`;
        console.log('Logging in with URL: ' + loginUrl);
        window.location.href = loginUrl;
    }

    (async function() {
        try {
            let shareToken = GM_getValue("share_token")
            if (isSTExpired() || !shareToken) {
                console.log('ST token is expired. Refreshing tokens...');
                const accessToken = await getAccessToken(refreshToken);
                console.log('Access token obtained: ' + accessToken);
                shareToken = await getShareToken(accessToken);
                console.log('Share token obtained: ' + shareToken);
                GM_setValue("share_token", shareToken)
            } else {
                console.log('ST token is still valid.');
            }
            autoLogin(shareToken);
        } catch (error) {
            console.error(error);
        }
    })();
})();

2 个赞

预测马上就要不简单了

mark

可以用下helper

我部署了,有bug

不错哦,mark

给年华佬 @linux 提issue

已经在github里提了

弄出来保存对话 默认无对话隔离的了 https://tokens.jerryz.com.cn/access/your_id

2 个赞