0

我想为 iOS 创建一个小部件来显示我的移动流量使用情况。要创建这个小部件,我想使用Scriptable

我试图创建所需的 Http GET 和 POST 请求来登录我的帐户,而不是读取所需的值,但我已经登录失败了。

这是我的代码:

// Variables used by Scriptable.
// These must be at the very top of the file. Do not edit.
// icon-color: red; icon-glyph: magic;

const loginPageUrl = "https://service.premiumsim.de";
const loginUrl = "https://service.premiumsim.de/public/login_check";

let cookies = null;
let sid = null;
let csrf_token = null;

//TODO: Use scriptable parameter
const username = "USERNAME";
const password = "PASSWORD";

await prepareLoginData();
await doLogin();

async function doLogin()
{
    try
    {
        // Post login data
        let req = new Request(loginUrl);
        req.method = 'POST';

        req.headers = {
            'Cookie': cookies,
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
            'Content-Type': 'application/x-www-form-urlencoded',
            'Origin': loginPageUrl,
            'Connection': 'keep-alive',
            'Referer': loginPageUrl,
            'Upgrade-Insecure-Requests': '1',
            'TE': 'Trailers'
        };

        // This looks the same as in firefox
        req.body = "_SID=" + sid + "&UserLoginType%5Balias%5D=" + username + "&UserLoginType%5Bpassword%5D=" + password + "&UserLoginType%5Blogindata%5D=&UserLoginType%5Bcsrf_token%5D=" + csrf_token;

        var resp = await req.loadString();
        await QuickLook.present(req.response);
        console.log(req.response.statusCode); // This should be 302 but is 200

        let view = new WebView();
        view.loadHTML(resp);
        await view.present();
    }
    catch (e)
    {
        console.error(e);
    }
}

async function prepareLoginData()
{
    try
    {
        // Get login page
        let req;
        req = new Request(loginPageUrl);
        req.method = 'GET';
        req.headers = {
            'Cookie': '',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
            'Content-Type': 'application/x-www-form-urlencoded',
            'Connection': 'keep-alive',
            'Upgrade-Insecure-Requests': '1',
            'TE': 'Trailers'
        };

        var resp = await req.loadString();

        // Get setted cookies
        let CookieValues = req.response.cookies.map(function (v)
        {
            return v.name + "=" + v.value
        });

        // Parse csrf token
        resp = resp.substr(resp.indexOf('UserLoginType_csrf_token'), 500);
        resp = resp.substr(resp.indexOf('value="') + 7);
        csrf_token = resp.substr(0, resp.indexOf('"'));

        console.log("Found csrf_token: " + csrf_token);

        cookies = CookieValues.join('; ') + '; isCookieAllowed=true';
        console.log("Found cookies: " + cookies);

        // Get sid
        sid = cookies.substring(5, cookies.indexOf(';'));
        console.log("Got _SID: " + sid);
    }
    catch (e)
    {
        console.error(e);
    }
}

加载登录页面按预期工作。解析 csrf 令牌也可以。将这些值发布到登录 url 时,我希望通过重定向到https://service.premiumsim.de/start获得状态代码 302 这是我使用 Firefox 看到的。

我已经复制了 firefox 也发送的所有标头,并且我向我的本地网络服务器发出了 POST 和 GET 请求,以查看传递的表单值是否对网络服务器正确。我不知道出了什么问题。

另请参阅:如何为登录请求生成 UserLoginType[_token] 这里使用另一种技术完成,但发送的内容相同。

4

1 回答 1

0

我发现,为什么它没有工作。

Scriptable 会自动加载重定向。这在这里不起作用,因为使用 302 响应发送的新 cookie 没有用于重定向。

解决方案是阻止此重定向并自行处理。

// This blocks the automatic redirect.
req.onRedirect = function (request)
{
    return null;
}

在此处查看完整的可编写脚本小部件: https ://github.com/BergenSoft/scriptable_premiumsim

编辑:我找不到 onRedirect 函数的工作示例,所以我问了 Scriptable 制造商,这是回应:

let url = "https://apple.com";
let req = new Request(url);
req.onRedirect = (req) => {
    log(req.url);
    return req;
}
await req.load();

希望这会帮助任何人。

于 2020-11-27T22:35:04.430 回答