web-dev-qa-db-ja.com

OAuth 2ベアラ認証ヘッダー

クライアントのAPIの更新により、HTTPBasicAuthicationメソッドがOAuth2 BearerAuthorizationヘッダーに置き換えられました。

古い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ヘッダーが含まれています。しかし、どのように?

13
rckoenes

多くの調査の結果、通話がリダイレクトされたときに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;

}];
15
rckoenes

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

4
MadNik

Djangoレストフレームワークとルーターでこの問題が発生している場合、問題はNSUrlRequestによってクリップされている末尾のスラッシュに関連している可能性があります。末尾のスラッシュがクリップされている場合はDjangoはリクエストをリダイレクトする必要があります。これを回避するには、Trailing_slash = Trueを次のように使用できます。

router = routers.DefaultRouter(trailing_slash=False)

そうすれば、認証ヘッダーもパラメーターも失われません。

これが誰かの時間を節約することを願っています。

1
Andrespch