المصادقة التلقائية لجهاز Android في شبكة Wi-Fi لمترو موسكو

كما تعلم ، تحتوي جميع سيارات مترو موسكو تقريبًا على نقاط وصول Wi-Fi ، يمكن للمستخدمين من خلالها الوصول إلى الإنترنت وقضاء وقت الرحلة إلى المترو من المنزل إلى العمل: قراءة الأخبار ، والتحقق من البريد ، ومشاهدة الأختام على YouTube ، وما إلى ذلك. .

يجب مصادقة كل جهاز قبل منحه حق الوصول إلى الإنترنت. لأول مرة ، يتم إرسال رسالة نصية قصيرة تحتوي على رمز إلى رقم الهاتف المحدد ، وبعد ذلك يتذكر النظام عنوان MAC الخاص بالجهاز وفي المستقبل ، للمصادقة ، يحتاج المستخدم فقط للنقر على الرابط "أدخل الإنترنت" والانتظار قليلاً.

عيب مثل هذه المؤسسة للنظام هو أنه حتى إذا لم يكن المستخدم بحاجة إلى متصفح ، وعلى سبيل المثال ، يريد الدخول إلى البريد أو قراءة تويتر باستخدام تطبيق متخصص ، فإنه لا يزال بحاجة إلى بدء المتصفح ، ومحاولة الوصول إلى بعض الصفحات ، وانتظر إعادة التوجيه ، انقر على الرابط ، انتظر حتى يتم تحميل صفحة الترحيب (اختياري: انظر الإعلان التجاري) ، وبعد ذلك فقط سيتمكن من استخدام التطبيق المطلوب.

إذا لم تكن زائرًا متكررًا للمترو ، فقد لا يسبب لك مثل هذا المخطط أي تهيج ، ومع ذلك ، إذا تم استخدامه يوميًا ، فإنه لا يزال يزعج ، كما قال أحد السياسيين المعروفين والجذاب: "يكفي لتحمل هذا!" ، اليوم سنقوم بالمصادقة التلقائية في مترو موسكو.

بادئ ذي بدء ، نحن بحاجة إلى تطبيق تاسكر. يمكنك الحصول عليه هنا (مقابل القليل من المال) ، أو في مكان ما هنا (على مسؤوليتك الخاصة والمخاطر). أنا شخصياً فضلت الخيار الأول ولم أندم عليه.

تاسكر هو تطبيق يسمح بالاعتماد على ظروف معينة (التاريخ / الوقت / الموقع / حالة الجهاز / قراءات المستشعر ، إلخ) لتنفيذ إجراءات معينة (إرسال رسائل / عرض الإخطارات / تشغيل / إيقاف / تشغيل واجهات بسيطة ، إلخ. د.). إن قوائم الشروط والإجراءات هائلة ببساطة وتعتمد على إصدار Android والأجهزة الخاصة بالجهاز ، لذلك لا فائدة من إحضارها بالكامل.

لذلك ، بعد بدء Tasker ، أولاً وقبل كل شيء ، تحتاج إلى ترجمة الواجهة إلى اللغة الإنجليزية ، لأن الترجمة عرجاء على ساقيه: الإعدادات-> الواجهة-> اللغة-> الإنجليزية وإعادة تشغيل التطبيق. الآن لدينا أربع علامات تبويب:
  • ملفات التعريف - تتحكم ملفات التعريف في الاتصال بين حالة الجهاز / الأحداث والمهام المختلفة ؛
  • المهام - المهام تصف تسلسل الإجراءات التي يجب القيام بها ؛
  • المشاهد - المشاهد مثل النماذج محلية الصنع التي يمكن للمهام إنشاؤها وتخصيصها ، وعناصر التحكم التي يمكنها تشغيل المهام عليها ؛
  • Vars - قائمة المتغيرات العامة التي يمكن استخدامها لتخزين البيانات بين عمليات إطلاق المهام.


انتقل إلى علامة التبويب " المهام" وأنشئ مهمة جديدة ، واسمها Metro Auth:



في النافذة التي تفتح ، نحتاج أولاً إلى تحديد العديد من المتغيرات. يتم تعريف المتغيرات على النحو التالي:


  • اسم المتغير - اسم المتغير ، يجب أن يبدأ برمز ٪ ويتكون من أحرف صغيرة. إذا كان اسم المتغير يحتوي على حرف كبير واحد على الأقل ، فسيصبح المتغير عموميًا ، لكننا لسنا بحاجة إليه ؛
  • To هي قيمة المتغير.

لذا ، نحتاج إلى إنشاء المتغيرات التالية:
  • %url — , . — ( ). HTTPS , HTTP;
  • %forms — HTML-, . — 'auth-form,hidden_form', - , , ( );
  • ٪ debug - سيؤدي هذا المتغير ، عند تعيينه إلى قيمة أخرى غير الصفر ، إلى عرض معلومات تصحيح إضافية ، مما سيساعدنا في إنشاء قائمة النماذج أعلاه.

بالإضافة إلى الإجراءات البسيطة ، يوفر لنا تاسكر القدرة على كتابة نصوص التعقيد التعسفي باستخدام العديد من الأدوات. سنستخدم جافا سكريبت بسيط:



هنا تحتاج إلى تعيين أقصى مهلة تنفيذ للبرنامج النصي - 50 ثانية ، في حالة الحاجة . تعتبر خانة الاختيار "خروج تلقائي" مسؤولة عن الإكمال التلقائي لأحد الإجراءات بعد الانتهاء من سلسلة الرسائل الرئيسية للبرنامج النصي. إذا تم استخدام الطلبات غير المتزامنة (حالتنا) أو وظيفة setTimeout ، فأنت بحاجة إلى إلغاء تحديد هذا المربع ، وتحديد إكمال الإجراء بنفسك باستخدام وظيفة exit () ؛ .

سأقدم البرنامج النصي نفسه في خيارين للتنسيق: هناك حاجة إلى تنسيق لائق إذا كنت ترغب في فحص البرنامج النصي دون أن تكسر عينيك ، ويسمح التنسيق على شاشة ضيقة للبرنامج النصي أن يبدو أكثر أو أقل لائقًا على الشاشة الضيقة للهاتف. في البداية ، تم كتابة البرنامج النصي على الهاتف في الإصدار "الضيق" ، وعندها فقط أعدت تنسيقه للمقالة:

البرنامج النصي بتنسيق لائق
function getUrl(url1,url2){
    url1=url1.split('?')[0];
    return url2.length?
        (/^http(s?):\/\//i.test(url2)?url2:
            (url2[0]=='/'?url1.split('/').slice(0,3).join('/')+url2:url1.split('/').slice(0,-1).join('/')+'/'+url2)
        ):url1;
}

function getVars(form,tag){
    vars='';
    fields=form.getElementsByTagName(tag);
    for(i=0;i<fields.length;i++)
        vars=vars+(i?'&':'')+fields[i].name+'='+fields[i].value;
    return vars;
}

function submit(xhr,request,form){
    request.url=getUrl(request.url,form.action);
    request.method=form.method;
    vars1=getVars(form,'input');
    vars2=getVars(form,'textarea');
    request.vars=vars1||vars2?(vars1?vars1:'')+(vars1&&vars2?'&':'')+(vars2?vars2:''):null;
    getPage(request,processPage,xhr);
}

function processPage(xhr,request){
    redir=xhr.getResponseHeader('Location');
    if(redir){
        if(redir==request.url) finalize(':  ');
        else{
            log('\n\n');
            getPage({'url':redir},processPage,xhr);
        }
    } else {
        forms=local('forms').split(',');
        id=null;
        for(i=0;i<forms.length;i++)
            if(xhr.response.getElementById(forms[i])) id=forms[i];
        if(id)submit(xhr,request,xhr.response.getElementById(id));
        else if(Number(local('debug'))){
            log('  :\n');
            forms=xhr.response.getElementsByTagName('form');
            if(forms.length)
                for(i=0;i<forms.length;i++)
                    log((i?', "':'"')+forms[i].id+'"');
            else log('');
            finalize();
        } else finalize(' ');
    }
}

function checkConn(xhr,request){
    redir=xhr.getResponseHeader('Location');
    if(redir){
        log('\n\n');
        getPage({'url':redir},processPage,xhr);
    } else {
        log('  ');
        finalize();
    }
}

function log(txt){
    logs=logs+(txt?txt:'');
}

function requestToText(request){
    return 'URL: '+request.url+'\nMethod: '+request.method+', Vars: '+request.vars+'\n\n';
}

function finalize(txt){
    log(txt);
    if(Number(local('debug'))) alert(logs);
    else if(txt) flashLong(txt);
    exit();
}

function getPage(request,func,xhr){
    if(!request.method) request.method='GET';
    if(!request.vars) request.vars=null;
    if(!xhr){
        xhr=new XMLHttpRequest();
        xhr.responseType="document";
        xhr.timeout=20*1000;
    }
    xhr.open(request.method,request.url,true);
    xhr.onload=function(){
        if(xhr.status==200 || xhr.status==401){
            log (requestToText(request)+'HTTP status: '+xhr.status+' '+xhr.statusText+'\n');
            func(xhr,request);
        } else {
            log(requestToText(request));
            finalize(' HTTP: '+xhr.status+' '+xhr.statusText);
        }
    }
    xhr.onerror=function(){
        log(requestToText(request));
        finalize(':  ');
    }
    xhr.ontimeout=function(){
        log(requestToText(request));
        finalize(':  ');
    }
    xhr.send(request.vars);
}

logs='';
getPage({'url':local('url')},checkConn);

البرنامج النصي في تنسيق الشاشة الضيقة
function getUrl(url1,url2){
  url1=url1.split('?')[0];
  return url2.length?
    (/^http(s?):\/\//i.test(url2)?
      url2:
        (url2[0]=='/'?
        url1.split('/').slice(0,3).join('/')+url2:
        url1.split('/').slice(0,-1).join('/')+
      '/'+url2)
    ):url1;
}

function getVars(form,tag){
  vars='';
  fields=form.getElementsByTagName(
    tag);
  for(i=0;i<fields.length;i++)
    vars=vars+(i?'&':'')+fields[i].name+
      '='+fields[i].value;
  return vars;
}

function submit(xhr,request,form){
  request.url=getUrl(request.url,
    form.action);
  request.method=form.method;
  vars1=getVars(form,'input');
  vars2=getVars(form,'textarea');
  request.vars=vars1||vars2?
    (vars1?vars1:'')+
    (vars1&&vars2?'&':'')+
    (vars2?vars2:'')
    :null;
  getPage(request,processPage,xhr);
}

function processPage(xhr,request){
  redir=xhr.getResponseHeader(
    'Location');
  if(redir){
    if(redir==request.url)
      finalize(':  '+
        '');
    else{
      log('\n\n');
      getPage({'url':redir},processPage,
        xhr);
    }
  } else {
    forms=local('forms').split(',');
    id=null;
    for(i=0;i<forms.length;i++)
      if(xhr.response.getElementById(
          forms[i]))
        id=forms[i];
    if(id)submit(xhr,request,
      xhr.response.getElementById(id));
    else if(Number(local('debug'))){
      log('  :\n');
      forms=xhr.response.
        getElementsByTagName('form');
      if(forms.length)
        for(i=0;i<forms.length;i++)
          log((i?', "':'"')+forms[i].id+'"');
      else log('');
      finalize();
    } else finalize(
      ' ');
  }
}

function checkConn(xhr,request){
  redir=xhr.getResponseHeader(
    'Location');
  if(redir){
    log('\n\n');
    getPage({'url':redir},processPage,
      xhr);
  } else {
    log('  '+
      '');
    finalize();
  }
}

function log(txt){logs=logs+(txt?txt:'');}

function requestToText(request){
  return 'URL: '+request.url+
    '\nMethod: '+request.method+
    ', Vars: '+request.vars+'\n\n';
}

function finalize(txt){
  log(txt);
  if(Number(local('debug'))) alert(logs);
  else if(txt) flashLong(txt);
  exit();
}

function getPage(request,func,xhr){
  if(!request.method)
    request.method='GET';
  if(!request.vars)request.vars=null;
  if(!xhr){
    xhr=new XMLHttpRequest();
    xhr.responseType="document";
    xhr.timeout=20*1000;
  }
  xhr.open(request.method,
    request.url,true);
  xhr.onload=function(){
    if(xhr.status==200 ||
        xhr.status==401){
      log (requestToText(request)+
        'HTTP status: '+xhr.status+' '+
        xhr.statusText+'\n');
        func(xhr,request);
    } else {
      log(requestToText(request));
      finalize(' HTTP: '+
        xhr.status+' '+xhr.statusText);
    }
  }
  xhr.onerror=function(){
    log(requestToText(request));
    finalize(':  '+
      '');
  }
  xhr.ontimeout=function(){
    log(requestToText(request));
    finalize(':  '+
      '');
  }
  xhr.send(request.vars);
}

logs='';
getPage({'url':local('url')},checkConn);

إن كتابة نص برمجي من لوحة مفاتيح الهاتف ، لسوء الحظ ، لا يحبذ التعليقات ، لكنني سأصف بإيجاز الخوارزمية:
  1. محاولة تحميل الصفحة المحددة في متغير ٪ url
  2. إذا لم يكن الرد يحتوي على رأس موقع HTTP ، فلن تتم إعادة توجيهنا ، مما يعني عدم الحاجة إلى المصادقة في الوقت الحالي ، اخرج
  3. نقوم بتحميل الصفحة التي تم توجيهنا إليها.
  4. إذا كان هناك رأس موقع ، فارجع إلى الخطوة 3
  5. إذا كانت الصفحة تحتوي على نموذج من القائمة في المتغير ٪ Forms ، فقم بعرضها والعودة إلى الخطوة 3
  6. في حالات أخرى ، نجحنا في المصادقة


بعد الانتهاء من البرنامج النصي ، حصلنا على هذه المهمة:



باستخدام الرمز الأول في الصف السفلي ، يمكنك محاولة تشغيله. حان الوقت للذهاب إلى مترو الأنفاق لإعداده!

في مترو الأنفاق ، المتصل بنقطة الوصول ، نحاول بدء المهمة. إذا لم تكن هناك مشاكل واضحة في توفر الخادم ، فسوف نرى رسالة مشابهة لتلك الموضحة في الشكل التالي على اليسار. أدناه نرى معرف النموذج الموجود في الصفحة الأخيرة التي تم تحميلها - نموذج مصادقة . من الواضح أن هذا النموذج هو عميلنا ، فنحن نقدم اسمه في متغير ٪ Forms ونقوم بتشغيل المهمة مرة أخرى ، ونحصل تقريبًا على ما هو مبين في الشكل التالي في المركز. معرف النموذج الجديد مخفي . أضفه إلى متغير ٪ Forms ، الآن ستكون قيمته ' auth-form ، hidden_form". نبدأ المهمة مرة أخرى ونرى تقريبًا ما هو موضح في الشكل التالي على اليمين - إما سيكون هناك نموذج بدون معرف ، أو علامة "غائبة" (اعتمادًا على خط المترو). إذا أطلقنا المتصفح الآن ، فسيكون من الواضح أننا اجتازنا المصادقة. قم بتعيين متغير التصحيح٪ إلى "0" ، وأغلق المهمة - لقد انتهينا.



الآن الأمر متروك لك لتكوين تشغيل المهام التلقائي عند الاتصال بنقطة الوصول المطلوبة. نذهب إلى علامة التبويب ملفات التعريف وننشئ ملف تعريف جديد سيتم تنشيطه بعد الاتصال بنقطة الوصول لمترو موسكو. بعد أن ننتهي من تشكيل وصف نقطة الوصول ، سيسألنا Tasker عن المهمة المراد ربط ملف التعريف بها ، بالطبع ، اختر Metro Auth .



فارق بسيط آخر: على الرغم من ندرة ، لا تزال المصادقة تطير ، على الرغم من عدم حدوث قطع من النقطة. إذا لم يكن هناك قطع اتصال ، لم يكن هناك إعادة اتصال ، مما يعني أن تاسكر لن يبدأ المهمة مرة أخرى ، لذلك سنقوم بتكوين تاسكر بحيث يتم التحقق من المصادقة تلقائيًا كل دقيقتين (الحد الأدنى للفاصل الزمني) ، لذلك نحتاج إلى النقر لفترة طويلة على الشرط المكون بالفعل لاستدعاء القائمة ، لإضافة حالة مؤقتة يتم فيها تعيين الفاصل الزمني.



هذا كل شيء. من الآن فصاعدًا وحتى تضطر إلى تغيير المعرّفات في متغير النماذج٪ ، تكون خوارزمية الإجراءات الخاصة بك عند إدخال حامل النقل كما يلي:
  1. قم بتشغيل Wi-Fi ؛
  2. انتظر رسالة "المصادقة مكتملة" على الشاشة ؛
  3. ابتسم بشكل غامض واستمر في عملك.


حدث: بناء على نصيحة الكمال الذاتيقمت بتصدير المشروع ووضعه في ملف واحد . يجب تنزيل هذا الملف ووضعه في المجلد / sdcard / Tasker / projects ، ثم تشغيل Tasker ، اضغط لفترة طويلة على رمز المنزل في الزاوية اليسرى السفلية لاستدعاء القائمة وحدد استيراد . في هذا الإصدار ، قمت بتسجيل الخروج مرة واحدة كل دقيقتين في ملف تعريف منفصل - يجب أن يعمل هذا بكفاءة أكبر.

Source: https://habr.com/ru/post/ar383109/


All Articles