Pull to refresh

Авторизация Вконтакте в ваших приложениях без компонента браузера

Reading time 10 min
Views 4.1K
Всем привет! Я разрабатываю Вконтакте плеер музыки для телефонов.
Понятно, что нужно использовать недавно вышедшее АПИ для десктоп и мобильных приложений. Все вполне логично, но есть одно но — авторизация производится только через компонент браузера, а именно мы должны юзеру показать html код, куда он введет свои данные.

То есть, простого метода апи в который отсылаем логин и пароль, а получаем сессию просто нет!
И что делать на устройствах без такого компонента?

Если html еще как-то можем отрендерить, то насчет javascript на j2me я молчу…
Тут на помощь приходит Firefox + Firebug + Firecookie.
Помучившись, за один день я разобрался, что и куда посылать, что бы получить сессию для использования АПИ.
Получилось 3 запроса, в каждом мы получаем нужные данные, и в конце сессию в формате JSON.
Далее я выкладываю понятный код для платформы j2me. Желающие без проблем переведут его на другие языки и платформы.
Код пока в бете, для общего понимания реализации, планирую сделать удобный класс для работы со всеми функциями АПИ Вконтакте.
Используется meapplicationdevelopers.dev.java.net/mobileajax.html, но правленый мной для поддержки просто html.

upload.com.ua/link/901600681

Работает так — VkApi.instance.login(«login», «pass»);
После этого у нас есть возможность получить данные сессии — getSid(), getUserId, getSecret(), getExpire()

Ну а генерация и посылание запросов — тема другой статьи.
Удачи в программировании!
  1. import com.sun.me.web.request.Arg;
  2. import com.sun.me.web.request.Request;
  3. import com.sun.me.web.request.Response;
  4. import org.json.me.JSONObject;
  5.  
  6. /**
  7.  *
  8.  * @author andryk
  9.  */
  10. public class VkApi {
  11.  
  12.     public static VkApi instance = new VkApi();
  13.     public static final String URL = "api.vkontakte.ru/api.php";
  14.  
  15.     //Заполните данными своего приложения
  16.  
  17.     public static final String APP_ID = "";
  18.     /*
  19.     Хеш приложения. 
  20.     Заходим браузером на страничку авторизации и ищем в коде переменную 'var auth_hash'
  21.     Этот хеш нужен для авторизации.
  22.     */
  23.     private static final String APP_HASH = "";
  24.  
  25.  
  26.     private static final Arg FORM_HEADER = new Arg("Content-Type""application/x-www-form-urlencoded");
  27.     protected String userId;
  28.     protected String sid;
  29.     protected String secret;
  30.     protected String expire;
  31.     protected boolean isLogged = false;
  32.     protected boolean needCaptcha = false;
  33.     protected String captchaSid="", captchaKey="";
  34.     public PopupBox captcha = null;
  35.  
  36.     protected VkApi() {
  37.     }
  38.  
  39.     protected String findS(String source) throws Exception {
  40.         System.out.println(source);
  41.         String pattern = "id='s' value='";
  42.         int start = source.indexOf(pattern);
  43.         String s = source.substring(start + pattern.length(), start + pattern.length() + 56);
  44.         if (s.length() != 56) {
  45.             throw new Exception("s not finded in form");
  46.         }
  47.         return s;
  48.     }
  49.  
  50.     public boolean isLogged() {
  51.  
  52.         return isLogged;
  53.     }
  54.  
  55.     public boolean isNeedCaptcha() {
  56.         return needCaptcha;
  57.     }
  58.  
  59.  
  60.     public String getSecret() {
  61.         return secret;
  62.     }
  63.  
  64.     public String getUserId() {
  65.         return userId;
  66.     }
  67.  
  68.     public String getSid() {
  69.         return sid;
  70.     }
  71.  
  72.     class NeedCaptchaException extends Exception {
  73.  
  74.         String sid;
  75.  
  76.         public NeedCaptchaException(String s) {
  77.             sid = s;
  78.         }
  79.  
  80.         public String getUrl() {
  81.             return "api.vk.com/captcha.php?sid=" + sid + "&s=1";
  82.         }
  83.  
  84.         public String getSid() {
  85.             return sid;
  86.         }
  87.     }
  88.  
  89.  
  90.  
  91.     public void setCaptchaKey(String captchaKey) {
  92.         this.captchaKey = captchaKey;
  93.     }
  94.  
  95.     public void login(String login, String password) {
  96.         try {
  97.  
  98.             Response result = Request.post("login.vk.com/"new Arg[]{
  99.                         new Arg("act""login")new Arg("app", APP_ID),
  100.                         new Arg("app_hash", APP_HASH)new Arg("captcha_key", captchaKey),
  101.                         new Arg("captcha_sid", captchaSid),
  102.                         new Arg("email", login)new Arg("pass", password),
  103.                         new Arg("permanent""1")new Arg("vk""")
  104.  
  105.                     }new Arg[]{FORM_HEADER}nullnullnull);
  106.  
  107.             //Если код редиректа - значит что то не так. 
  108.             if (result.getCode() == 302) {
  109.                 String sid = null;
  110.                 int start = -1;
  111.                 for (int i = 0 ; i < result.getHeaders().length; i++) {
  112.                     if (result.getHeaders()[i].getKey().toLowerCase().equals("location")) {
  113.                         String l = result.getHeaders()[i].getValue();
  114.                         start = l.indexOf("m=1&cs=");
  115.                         int end = l.indexOf("&", start + 7);
  116.                         sid = l.substring(start + 7, end);
  117.                         break;
  118.                     }
  119.  
  120.                 }
  121.                 //Или нужен ввод капчи
  122.                 if(start > 0 0)
  123.                     throw new NeedCaptchaException(sid);
  124.                 //Или неправильный логин/пароль
  125.                 else
  126.                     throw new Exception("Wrong login/pass");
  127.             }
  128.             needCaptcha = false;
  129.  
  130.             //Посылаем новый запрос с куками от предыдущего
  131.             Response result2 = Request.get("login.vk.com/?vk="nullnullnull, result.getCookies());
  132.             //Находим SID
  133.             //.getResult().getRaw() - тело ответа
  134.             s = findS(result2.getResult().getRaw());
  135.  
  136.             //Последний 3 запрос, в котором мы найдем искомые данные
  137.             Response result3 = Request.get("vkontakte.ru/login.php?app="+APP_ID+"&layout=popup&type=browser&settings=1054"nullnullnullnew Arg[]{new Arg("remixsid", s)});
  138.  
  139.             String r = result3.getResult().getRaw();
  140.             int start = r.indexOf("{\"mid\"");
  141.             //Нашли наш JSON обьект с данными сессии
  142.             String sess = r.substring(start, r.indexOf("}", start) + 1);
  143.             //Нужно считать его
  144.             JSONObject session = new JSONObject(sess);
  145.             //Запоминаем данные
  146.             userId = session.getString("mid");
  147.             sid = session.getString("sid");
  148.             secret = session.getString("secret");
  149.             expire = session.getString("expire");
  150.             isLogged = true;
  151.  
  152.         } catch (NeedCaptchaException e) {
  153.             //Выводим юзеру капчу, адрес картинки - e.getUrl()
  154.             //После этого устанавливаем код setCaptchaKey(String key)
  155.             //И делаем логин заново
  156.  
  157.         } catch (Exception e) {
  158.             isLogged = false;
  159.             //Действия если логин/пароль неправильные
  160.         }
  161.  
  162.     }
  163. }
Tags:
Hubs:
+8
Comments 16
Comments Comments 16

Articles