M
16 августа 2023 г. 17:24

OAuth2.0 через VK, получение email

QOAuth2AuthorizationCodeFlow, OAuth2, VK

Разбираюсь довольно большое количество времени с OAuth через вк, используя QOAuth2AuthorizationCodeFlow и застрял на вопросе получения email пользователя, разобрался с тем как получать всю остальную информацию о пользователе, но как получить почту не могу понять, в документации просто нет информации об этом, неужели это не предусмотренно VK API?
Вот мой тестовый код, тут я получаю имя и фамилию пользоватея и его screen_name, читал на каком-то форуме, что email возвращается VK вместе с токеном, поэтому попробовал с помощью QObject::connect(this->replyHandler(), &QAbstractOAuthReplyHandler::replyDataReceived, this, &VkOAuth2::onReplyDataReceived); получить QByteArray с ответом от Vk, но email там нет, только токен и id пользователя, подскажите, кто работал с VK API, как получить почту пользователя?

  1. VkOAuth2::VkOAuth2(QObject *parent)
  2. : QOAuth2AuthorizationCodeFlow{parent}
  3. {
  4. auto replyHandler = new QOAuthHttpServerReplyHandler(REDIRECT_URI.port(), qApp);
  5. setReplyHandler(replyHandler);
  6. setAccessTokenUrl(TOKEN_URL);
  7. setAuthorizationUrl(AUTH_URL);
  8. setClientIdentifier(CLIENT_ID);
  9. setClientIdentifierSharedKey(CLIENT_SECRET);
  10. setScope(SCOPE_MASK);
  11. QObject::connect(this, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser, &QDesktopServices::openUrl);
  12. //Сигнал granted излучается при успешной авторизации
  13.  
  14. QObject::connect(this->replyHandler(), &QAbstractOAuthReplyHandler::replyDataReceived, this, &VkOAuth2::onReplyDataReceived);
  15. //this->replyHandler()->replyDataReceived();
  16. QObject::connect(this, &QOAuth2AuthorizationCodeFlow::replyDataReceived, this, &VkOAuth2::onReplyDataReceived);
  17.  
  18. QObject::connect(this, &QOAuth2AuthorizationCodeFlow::granted, [this]() {
  19. const QUrl getEmail{ "https://api.vk.com/method/account.getProfileInfo" };
  20. const QString token = this->token();
  21. //qDebug() << token;
  22. //Vk требует указывать версию API в параметрах запроса. Укажем 5.131
  23. auto network_reply = get(getEmail, { { "fields", "screen_name" }, { "v", 5.131 } });
  24. QObject::connect(network_reply, &QNetworkReply::finished, [network_reply] {
  25. //Ответ будет удалён позже, когда отработают все связанные
  26. //с ним сигнально-слотовые соединения,
  27. //поэтому такое удаление безопасно
  28. network_reply->deleteLater();
  29.  
  30. QJsonDocument response = QJsonDocument::fromJson(network_reply->readAll());
  31. //qDebug() << response;
  32. });
  33. });
  34. this->grant();
  35.  
  36. }
2

Вам это нравится? Поделитесь в социальных сетях!

5
Evgenii Legotckoi
  • 16 августа 2023 г. 18:39

Что у вас написано в SCOPE_MASK ? там есть упоминание о email ?
email - это отдельный scope, без этого разрешения вы не получите email

    M
    • 16 августа 2023 г. 19:34

    да, конечно SCOPE_MASK = "email"

      Evgenii Legotckoi
      • 16 августа 2023 г. 22:47
      • (ред.)

      Хорошо, значит остаётся лишь одно. Вы не там ищете email.

      В официальной документации на VK API написано следующее:

      Если у пользователя указан email, а приложением были запрошены соответствующие права, сервер также вернет email пользователя.

      Ознакомиться с документацией можно здесь VK API authcode

      Поэтому пытаться найти email в запросе getProfileInfo может быть изначально бесполезно.

      Вам нужно проверить, что возвращается в момент авторизации.

      Если не запрашивать вообще никаких разрешений, то API вернёт это:

      1. {
      2. "access_token": "533bacf01e11f55b536a565b57531ac114461ae8736d6506a3",
      3. "expires_in": 43200,
      4. "user_id": 66748
      5. }

      Если же запросить и email, то должно быть примерно так

      1. {
      2. "access_token": "533bacf01e11f55b536a565b57531ac114461ae8736d6506a3",
      3. "expires_in": 43200,
      4. "user_id": 66748,
      5. "email": "example@example.com"
      6. }

      В общем, если верить документации на QOAuth2AuthorizationCodeFlow После авторизации кроме токена через метод

      1. const QString token = this->token();

      Вам возможно стоит проверить ещё и экстра токены с помощью метода extraTokens

      1. const QVariantMap tokens = this->extraTokens();

      Полагаю, что там может быть email и всякая дополнительная шелуха.

        M
        • 17 августа 2023 г. 0:18
        • (ред.)
        • Ответ был помечен как решение.

        Да, действительно, оказалось что почта к моему аккаунту была привязана, но ждала подтверждение, а я столько времени потратил впустую, когда проблема была в аккаунте, используя другой аккаунт, я получил email с помощью const QVariantMap tokens = this->extraTokens();

          M
          • 17 августа 2023 г. 0:26

          Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.

            Комментарии

            Только авторизованные пользователи могут публиковать комментарии.
            Пожалуйста, авторизуйтесь или зарегистрируйтесь