【问题标题】:OAuth 2 bearer Authorization headerOAuth 2 不记名授权标头
【发布时间】:2012-08-18 22:50:47
【问题描述】:

随着客户端 API 的更新,HTTPBasicAuthication 方法已替换为 OAuth2 Bearer Authorization 标头。

使用旧 API,我会执行以下操作:

NSURLCredential *credential = [NSURLCredential credentialWithUser:self.account.username 
                                                         password:self.account.token 
                                                      persistence:NSURLCredentialPersistenceForSession];

NSURLProtectionSpace *space = [[NSURLProtectionSpace alloc] initWithHost:kAPIHost
                                                                    port:443
                                                                protocol:NSURLProtectionSpaceHTTPS
                                                                   realm:@"my-api"
                                                    authenticationMethod:NSURLAuthenticationMethodHTTPBasic];

但这不适用于Bearer 标头。

现在通常我会像这样添加我自己的标题:

NSString *authorization = [NSString stringWithFormat:@"Bearer %@",self.account.token];
[urlRequest setValue:authorization forHTTPHeaderField:@"Authorization"];

但这个解决方案的问题在于 API 将大部分调用重定向到其他 URL,这与安全性有关。 在NSURLRequest 被重定向后,Authorization 标头已从请求中删除,并且由于我无法将 Bearer 方法添加到 NSURLCredentialStorage,因此在重定向后无法再进行身份验证。

什么是好的解决方案?我只能想抓住重定向并修改NSURLRequest,因此它确实包含Bearer 标头。但是怎么做呢?

【问题讨论】:

    标签: ios nsurlconnection oauth-2.0 nsurlrequest


    【解决方案1】:

    经过大量研究,我发现当呼叫被重定向时,我只需要替换NSURLRequest。

    没有我想要的那么好,但确实有效。

    我使用AFNetworking 并添加了重定向块,然后检查Authorization 标头是否仍然设置,如果没有我创建一个新的NSMutableURLRequest 并设置所有属性以匹配旧请求(我知道我可以刚刚创建了一个可变副本):

    [requestOperation setRedirectResponseBlock:^NSURLRequest *(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse) {
    
        if ([request.allHTTPHeaderFields objectForKey:@"Authorization"] != nil) {
            return request;
        }
    
        NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:request.URL cachePolicy:request.cachePolicy timeoutInterval:request.timeoutInterval];
        NSString *authValue = [NSString stringWithFormat:@"Bearer %@", self.account.token];
        [urlRequest setValue:authValue forHTTPHeaderField:@"Authorization"];
    
        return  urlRequest;
    
    }];
    

    【讨论】:

    • 你是个传奇。我遇到了同样的问题,处理重定向修复了它。
    【解决方案2】:

    我正在使用 AFNetworking 库

    找到AFHttpClient.m,你就有了方法

    - (void)setAuthorizationHeaderWithToken:(NSString *)token {
        [self setDefaultHeader:@"Authorization" value:[NSString stringWithFormat:@"Token token=\"%@\"", token]];
    }
    

    将此方法替换为以下内容,或者如果您需要它以实现向后兼容性,请使用其他名称添加并使用该名称

    - (void)setAuthorizationHeaderWithToken:(NSString *)token {
        [self setDefaultHeader:@"Authorization" value:[NSString stringWithFormat:@"Bearer %@", token]];
    }
    

    然后使用 oauth 访问令牌发出请求。 (以下是GET方法服务)

        NSURL *url = [EFServiceUrlProvider getServiceUrlForMethod:methodName];
        AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
        [httpClient setAuthorizationHeaderWithToken:@"add your access token here"];
    
        [httpClient getPath:@"" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSString *response = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            //
        }];
    

    更新


    在 matt 编写的 AFNetworking 上使用 Oauth2 客户端

    https://github.com/AFNetworking/AFOAuth2Client

    【讨论】:

    • 不,当请求被重定向时,你将丢失不记名令牌。
    【解决方案3】:

    如果您碰巧在 Django REST 框架和路由器中遇到此问题,则该问题可能与 NSUrlRequest 剪切的尾部斜杠有关。如果尾部斜杠被剪裁,那么 django 将不得不重定向您的请求,为避免这种情况,您可以像这样使用 Trailing_slash = True

    router = routers.DefaultRouter(trailing_slash=False)
    

    这样您的授权标头和参数都不会丢失。

    希望这可以节省一些时间。

    【讨论】:

    • 没有 Django,但是 ASP.net 和我也用 PHP 看到了它。一旦发生 URL 重定向,Authorization 就会被清除。这是正常行为,在收到 403 后,将使用 Authorization 标头再次完成调用。问题是 bearer 标头没有得到很好的支持。
    • 哇。我们一直在使用 Django rest 并试图弄清楚为什么 IOS 没有发送 Authorization 令牌标头,就是这样,NSURLRequest 正在删除尾部斜杠
    猜你喜欢
    • 2012-06-19
    • 2016-07-31
    • 1970-01-01
    • 2016-06-14
    • 2013-04-19
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多