クライアントの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
ヘッダーが含まれています。しかし、どのように?
多くの調査の結果、通話がリダイレクトされたときに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;
}];
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クライアントを使用する
Djangoレストフレームワークとルーターでこの問題が発生している場合、問題はNSUrlRequestによってクリップされている末尾のスラッシュに関連している可能性があります。末尾のスラッシュがクリップされている場合はDjangoはリクエストをリダイレクトする必要があります。これを回避するには、Trailing_slash = Trueを次のように使用できます。
router = routers.DefaultRouter(trailing_slash=False)
そうすれば、認証ヘッダーもパラメーターも失われません。
これが誰かの時間を節約することを願っています。