Яндекс.Метрика

    Ни о чём

    Pop-up авторизации ВКонтакте для протокола OAuth 2.0

    На данный момент существует 2 возможности авторизации в социальной сети «В Контакте»:
    • Open API
    • OAuth 2.0

    Первый устаревший, а второй — модный, прогрессивный и стандартизированный.

    Но, однако, переходя на новый способ, я заметил, что нигде в документации «В Контакте» не говорится, как сделать авторизационное окошко небольшим попапом.

    На странице "Авторизация сайтов" сказано: «Для начала процесса авторизации необходимо создать окно браузера и открыть в нём диалог авторизации». Но ни слова не сказано о том, как создать такое окно.

    У Facebook есть свой метод JavaScript FB.login для этой цели. У OpenAPI «В Контакте» есть VK.Auth.login. А для OAuth 2 «В Контакте» нет ничего.

    «Ну что же, challenge accepted», — сказал я себе. И решил написать свой метод.
    Вот что у меня получилось:
    function vk_popup(options)
    {
      var
        screenX = typeof window.screenX != 'undefined' ? window.screenX : window.screenLeft,
        screenY = typeof window.screenY != 'undefined' ? window.screenY : window.screenTop,
        outerWidth = typeof window.outerWidth != 'undefined' ? window.outerWidth : document.body.clientWidth,
        outerHeight = typeof window.outerHeight != 'undefined' ? window.outerHeight : (document.body.clientHeight - 22),
        width = options.width,
        height = options.height,
        left = parseInt(screenX + ((outerWidth - width) / 2), 10),
        top = parseInt(screenY + ((outerHeight - height) / 2.5), 10),
        features = (
          'width=' + width +
            ',height=' + height +
            ',left=' + left +
            ',top=' + top
          );
      return window.open(options.url, 'vk_oauth', features);
    }

    function doLogin() {
      var win;
      var redirect_uri = 'http://MY_APP/vk_auth/';
      var uri_regex = new RegExp(redirect_uri);
      var url = 'http://oauth.vkontakte.ru/authorize?client_id=CLIENT_ID&display=popup&redirect_uri=' + redirect_uri;
      win = vk_popup({
        width:620,
        height:370,
        url:url
      });

      var watch_timer = setInterval(function () {
        try {
          if (uri_regex.test(win.location)) {
            clearInterval(watch_timer);

            setTimeout(function () {
              win.close();
              document.location.reload();
            }, 500);
          }
        } catch (e) {

        }
      }, 100);
    }


    * This source code was highlighted with Source Code Highlighter.

    Сначала создаю окно с диалогом авторизации, которое выглядит в точности, как аналогичное для OpenAPI.

    image

    Затем таймером отслеживаю изменение текущего URL в этом окошке, чтобы определить, когда «В Контакте» перенаправит на мой URL авторизации. И жду 500 мс, чтобы сервер уж точно успел обработать запрос. После этого перезагружаю основное окно своего сайта.

    Обёртывать обращение к win.location в try {} catch(e) {} необходимо, потому что политика кросс-доменности не позволяет узнавать URL'ы окон других сайтов.

    Хотелось также сделать это через какой-нибудь Observer, который бы наблюдал за изменением win.location и оповещал о событии, но подходящих примеров я не нашёл и JavaScript не моя основная специализация, поэтому остановился на реализации таймером. Буду благодарен, если кто-нибудь подскажет, как перевести на события.

    Надеюсь, эта заметка будет полезной людям.