<form novalidate="" data-remote="true" method="post" id="login_form" class="s-form login_form validateble" action="/ajax/login/"> <input type="hidden" value="180351c318af67fa0ec59ecad9ebae72" name="state"> <input type="hidden" value="habrahabr" name="consumer"> <div class="s-field s-with-error"> <input type="email" data-validate_url="/ajax/validate/email/" id="email_field" tabindex="1" autofocus="" data-required="true" name="email" placeholder="E-mail" value=""> </div> <div class="s-field s-with-error"> <input type="password" tabindex="2" name="password" data-required="true" placeholder="" value=""> </div> <div class="s-field"> <input type="hidden" name="captcha"> <input type="hidden" id="recaptcha_challenge_field" name="recaptcha_challenge_field"> <input type="text" name="recaptcha_response_field" id="recaptcha_response_field" data-required="true" placeholder=" " value="" autocomplete="off" tabindex="3"> <div class="icon_captcha"></div> <script src="//www.google.com/recaptcha/api/challenge?k=6LftHuoSAAAAAORONRXn_6xb2f_QCtXqfbRPfY2e" type="text/javascript"> </script> <input type="hidden" value="recaptcha" name="captcha_type"> </div> </form>
state
field is a kind of unique identifier that is generated for each login, the consumer
for us is a static value and is always equal to habrahabr
, the captcha
value is always empty, recaptcha_challenge_field
unique captcha identifier, captcha_type
always recaptcha
. <div class="userpanel silver"> <div class="bottom"> <a href="http://habrahabr.ru/tracker/"></a> <a class="count" href="http://habrahabr.ru/tracker/">+2</a> <a href="http://habrahabr.ru/conversations/"></a> <a href="http://habrahabr.ru/users/BloodUnit/favorites/"></a> </div> </div>
function init() { this.initStage = ST_PRE; // , ST_LOGIN, , this.loginData = ["https://id.tmtm.ru/ajax/login/", "email", "password", "consumer=habrahabr&captcha_type=recaptcha&captcha="]; // URL , name e-mail , this.dataURL = "http://habrahabr.ru/"; // URL this.viewURL = "http://habrahabr.ru/tracker/"; // URL this.cookieDomain = "habrahabr.ru"; // }
function process(aData, aHttp) { switch (this.stage) { /* , state */ case ST_PRE: this.getHtml("https://auth.habrahabr.ru/login/"); return false; /* , state recaptcha, */ case ST_PRE_RES: var recaptchaScriptLink = aData.match(/(\/\/www.google.com\/recaptcha\/api\/challenge\S+?)"/); var state = aData.match(/state=([\w\n]+)/); if (recaptchaScriptLink && state) { this.originPostData = this.loginData[LOGIN_POST]; this.loginData[LOGIN_POST] += "&state=" + encodeURIComponent(state[1]); this.referer = this.loginData[LOGIN_URL] + "?" + "&state=" + encodeURIComponent(state[1]) + "&consumer=habrahabr"; this.getHtml("https:" + recaptchaScriptLink[1]); return false; } this.onError(); break; /* */ case ST_PRE_RES + 1: var recaptchaUid = aData.match(/challenge\s*:\s*'(\S+?)'/); if (recaptchaUid) { this.loginData[LOGIN_POST] += "&recaptcha_challenge_field=" + encodeURIComponent(recaptchaUid[1]); this.openCaptchaDialog(this.id, this.user, "https://www.google.com/recaptcha/api/image?c=" + recaptchaUid[1]); return false; } this.onError(); break; /* */ case ST_PRE_RES + 2: this.loginData[LOGIN_POST] += "&recaptcha_response_field=" + encodeURIComponent(aData); this.stage = ST_LOGIN; return this.process(aData, aHttp); break; /* */ case ST_LOGIN: this.getHtml(this.loginData[LOGIN_URL], this.loginData[LOGIN_POST], { Referer: this.referer }); return false; /* */ case ST_LOGIN_RES: this.loginData[LOGIN_POST] = this.originPostData; var habrRedirectLink = aData.match(/'(.*?)'/); if (habrRedirectLink) { this.getHtml(habrRedirectLink[1]); } this.stage = ST_DATA; return true; } return this.baseProcess(aData, aHttp); }
false
, the sequence value will be incremented.this.getHtml
and this.openCaptchaDialog
methods will be passed to the next stage.ST_LOGIN
stage, we need to set the Referer value, otherwise authorization will not pass. Google Chrome does not allow setting this parameter (and this is the standard , albeit in Working Draft), respectively, authorization via the plugin will not work in it, but if you are logged in, everything will work fine!ST_LOGIN
stage, Habr returns a script with a redirect to the main one that looks like this: window.location.href = 'https://habrahabr.ru/ac/entrance/?token=5a15a5d48c7fdeaed5ab20e852107dc6&state=26593fdea0963d8241aab3f20a6893b4&time=1390388377&sign=bb8f45d63c768ed6aebc5ae2bb22de3b';
function checkLogin(aData, aHttp) { switch (this.stage) { /* HTML */ case ST_CHECK: this.getHtml(this.dataURL); return false; /* , , */ case ST_CHECK + 1: var loginLink = aData.match(/<a.+?class="login"/); if (!loginLink) { this.stage = ST_DATA; this.getHtml(this.dataURL); return true; } else { this.stage = this.initStage; return this.process(""); } } this.onError(); return true; }
function getCount(aData) { var userMenu = aData.match(/userpanel[\s\S]*?charge_string/); if (!userMenu) { return -1; } else { var counter = 0; var counterRegex = /class="count"[^>]*>\+?(\d*)/g var counterResult; while ((counterResult = counterRegex.exec(userMenu[0])) !== null) { counter += +counterResult[1] || 0; } return counter; } }
Source: https://habr.com/ru/post/210020/
All Articles