如何使用Google离线访问令牌在iOS后台进行身份验证?

The*_*ter 5 iphone authentication objective-c ios google-oauth

精简版:

我想使用Objective OA的Google OAuth2客户端创建一个有效的GTMOAuth2Authentication对象供我在我的应用中使用,我可以从后端获取一个离线访问令牌.我怎么能做到这一点?

我的情况:

我的应用程序使用Analytics只读范围来获取有关用户网站的一些数据.我实现这一目标的方法是使用GTMOAuth2ViewControllerTouchGoogle OAuth2客户端为Objective C提供的ViewController 登录.然后,它为我提供了有效GTMOAuth2Authentication对象,我可以使用该对象通过Google API客户端查询Google Analytics .

现在,我们不希望为用户提供Google Analytics访问权限(有些人没有Google帐户,一般情况下,我们希望通过应用程序保持信息简单).这意味着我们必须使用我们的帐户登录(可以访问所有网站的Google Analytics数据).显然我们无法向用户提供我们的凭据,因此我们必须找到解决方案.

我的计划:

我认为这个问题可以通过从我们的后端请求我们的(离线访问)令牌字符串(通过SSL加密),将其保存到用户的钥匙串并在应用程序中进一步使用它来查询分析来解决.然后,我们让用户登录我们的服务(以便我们确定用户可以访问哪些网站),并显示数据.

我的问题:

我到处搜索,查看了谷歌(非常薄)的文档,检查了GTMOAuth2Authentication源代码,但我似乎无法解决这个问题.在我看来会有这样的解决方案(因为我在CMS中使用类似的方法让用户发布到我们的Facebook墙上),所以我在这里缺少什么?

当前登录代码:

GTMOAuth2ViewControllerTouch *viewController = [[GTMOAuth2ViewControllerTouch alloc]
                                                    initWithScope:scope
                                                    clientID:kMyClientID
                                                    clientSecret:kMyClientSecret
                                                    keychainItemName:kKeychainItemName
                                                    completionHandler:
    ^(GTMOAuth2ViewControllerTouch *viewController, GTMOAuth2Authentication *auth, NSError *error) {
        if (error != nil) {
            // Authentication failed
            DebugLog(@"Failed!");
        } else {
            // Authentication succeeded
            DebugLog(@"Success!");

            // Update interface
            self.loginButton.hidden = YES;

            self.authentication = auth;
        }
    }]; 
Run Code Online (Sandbox Code Playgroud)

我尝试过的:

我尝试手动创建一个GTMOAuth2Authentication对象并自己设置所有参数(范围,clientid,secretid,访问令牌,刷新令牌,callbackuri,令牌url等),但当我尝试使用时,我收到了401:Login Required错误查询对象.所以我想这不是做到这一点的方法.

链接:

谢谢阅读!

bal*_*oth 6

您不需要GTMOAuth2Authentication实例.您需要的是创建自己的类来实现GTMFetcherAuthorizationProtocol协议,并将其指定为您的授权人.

MyAuth *myAuth = [[MyAuth alloc] initWithAccessToken:accessToken];
googleService.authorizer = myAuth;
Run Code Online (Sandbox Code Playgroud)

此类需要根据您已有的访问令牌授权请求.这个类的代码应该与此类似.

@interface MyAuth : NSObject<GTMFetcherAuthorizationProtocol>     
    @property (copy, nonatomic) NSString *accessToken;
    @property (copy, readonly) NSString *userEmail;
@end

@implementation MyAuth

- (void)authorizeRequest:(NSMutableURLRequest *)request
                delegate:(id)delegate
       didFinishSelector:(SEL)sel {
    if (request) {
        NSString *value = [NSString stringWithFormat:@"%s %@", GTM_OAUTH2_BEARER, self.accessToken];
        [request setValue:value forHTTPHeaderField:@"Authorization"];
    }

    NSMethodSignature *sig = [delegate methodSignatureForSelector:sel];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
    [invocation setSelector:sel];
    [invocation setTarget:delegate];
    [invocation setArgument:(__bridge void *)(self) atIndex:2];
    [invocation setArgument:&request atIndex:3];
    [invocation invoke];
}

- (void)authorizeRequest:(NSMutableURLRequest *)request
       completionHandler:(void (^)(NSError *error))handler {
    if (request) {
        NSString *value = [NSString stringWithFormat:@"%@ %@", @"Bearer", self.accessToken];
        [request setValue:value forHTTPHeaderField:@"Authorization"];
    }
}

- (BOOL)isAuthorizedRequest:(NSURLRequest *)request {
    return NO;
}

- (void)stopAuthorization {
}

- (void)stopAuthorizationForRequest:(NSURLRequest *)request {
}

- (BOOL)isAuthorizingRequest:(NSURLRequest *)request {
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.