VKCOM / vk-ios-sdk

iOS library for working with VK API, authorization through VK app, using VK functions
MIT License
298 stars 164 forks source link

Авторизация через приложение по прежнему не работает, но с нюансом. #601

Closed VFeed closed 1 year ago

VFeed commented 1 year ago

При попытке авторизоваться через приложение, все так же редиректит в приложение, но не отображает алерта на авторизацию. Нюанс заключается в том, что у меня по неведомой причине все работает, но не работает ни у кого больше в команде, а так же у тестовой группы пользователей.

Это не зависит от аккаунта, устройства или системы. Версия сдк 1.6.3.

Igralino commented 1 year ago

Проверьте, что вы не передаете поле "VKAuthorizationOptionsEnableProviders" и что баг воспроизводится именно на релизе 1.6.3.

Будем благодарны, если сможете приложить скринкаст с воспроизведением проблемы и информацию о версии VK App у пользователей, которые с ней сталкиваются.

VFeed commented 1 year ago

Простите за долгий ответ, даю информацию. Версии VK App, где не работает авторизация 7.43.1 У меня стоит 7.44. Видео в котором виден переход в вк апп, но не вызывается при этом алерт авторизации https://drive.google.com/file/d/1kAlGZpRRvBHROqZvqdsoHJwikT4ZPgQF/view?usp=sharing. Думаю показывать аналогично работающую авторизацию нет смысла. Так выглядит код авторизации(в форке была убрана переменная provideEnabled, в попытках поправить ситуацию, но это никак не помогло)

+ (void)authorize:(NSArray *)permissions withOptions:(VKAuthorizationOptions)options {
    permissions = permissions ?: @[];
    NSMutableSet *permissionsSet = [NSMutableSet setWithArray:permissions];

    if (options & VKAuthorizationOptionsUnlimitedToken) {
        [permissionsSet addObject:VK_PER_OFFLINE];
    }
    VKSdk *instance = [VKSdk instance];
    instance.lastKnownOptions = options;

    if ([self accessToken] && [instance.permissions isEqualToSet:permissionsSet]) {
        instance.accessToken = [self accessToken];
        return;
    }
    if (instance.authState == VKAuthorizationAuthorized) {
        instance.authState = VKAuthorizationInitialized;
    }

    instance.permissions = [permissionsSet copy];
    permissions = [permissionsSet allObjects];

    //BOOL providersEnabled = options & VKAuthorizationOptionsEnableProviders;

    BOOL vkApp = [self vkAppMayExists]
            && instance.authState == VKAuthorizationInitialized;

    BOOL safariEnabled = !(options & VKAuthorizationOptionsDisableSafariController);

    NSString *clientId = instance.currentAppId;
    VKAuthorizationContext *authContext =
    [VKAuthorizationContext contextWithAuthType:vkApp ? VKAuthorizationTypeApp : VKAuthorizationTypeSafari
                                       clientId:clientId
                                    displayType:VK_DISPLAY_MOBILE
                                          scope:permissions
                                         revoke:YES];
    NSURL *urlToOpen = [VKAuthorizeController buildAuthorizationURLWithContext:authContext];

    if (vkApp) {

        UIApplication *application = [UIApplication sharedApplication];

        // Since iOS 9 there is a dialog asking user if he wants to allow the running app
        // to open another app via URL. If user rejects, then no VK SDK callbacks are called.
        // Fixing this using new -[UIApplication openURL:options:completionHandler:] method (iOS 10+).

#ifdef __AVAILABILITY_INTERNAL__IPHONE_10_0_DEP__IPHONE_10_0
        if ([application respondsToSelector:@selector(openURL:options:completionHandler:)]) {

            NSDictionary *options = @{ UIApplicationOpenURLOptionUniversalLinksOnly: @NO };

            [application openURL:urlToOpen options:options completionHandler:^(BOOL success) {

                if (!success) {

                    VKMutableAuthorizationResult *result = [VKMutableAuthorizationResult new];
                    result.state = VKAuthorizationError;
                    result.error = [NSError errorWithVkError:[VKError errorWithCode:VK_API_CANCELED]];

                    [[VKSdk instance] notifyDelegate:@selector(vkSdkAccessAuthorizationFinishedWithResult:) obj:result];
                }
            }];
        } else {
            [application openURL:urlToOpen];
        }
#else
        [application openURL:urlToOpen];
#endif

        instance.authState = VKAuthorizationExternal;

    } else if (safariEnabled && [SFSafariViewController class] && instance.authState < VKAuthorizationSafariInApp) {
        SFSafariViewController *viewController = [[SFSafariViewController alloc] initWithURL:urlToOpen];
        viewController.delegate = instance;
        [viewController vks_presentViewControllerThroughDelegate];
        instance.presentedSafariViewController = viewController;

        instance.authState = VKAuthorizationSafariInApp;
    } else {
        //Authorization through popup webview
        [VKAuthorizeController presentForAuthorizeWithAppId:clientId
                                             andPermissions:permissions
                                               revokeAccess:YES
                                                displayType:VK_DISPLAY_IOS];
        instance.authState = VKAuthorizationWebview;
    }
}

Строка, которая передаются в urlToOpen vkauthorize://authorize?sdk_version=1.6.3&client_id=#CLIENT_ID#&scope=groups%2Cstats%2Cmarket%2Cusers%2Cdocs%2Cstories%2Cmessages%2Coffline%2Cnotify%2Cnotes%2Cmanage%2Cfriends%2Cphotos%2Cnotifications%2Cwall%2Cstatus%2Cvideo&revoke=1&v=5.131

Igralino commented 1 year ago

В версиях VK App 7.43.х авторизация через приложение может работать некорректно, в связи с чем мы настоятельно рекомендуем использовать дефолтное поведение метода authorize в версии 1.6.3. То есть использовать авторизацию через браузер, а не через VK App