Заголовок авторизации OAuth 2
С обновлением API-интерфейса клиента метод HTTPBasicAuthication заменил заголовок авторизации OAuth2 Bearer
.
Со старым 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
заголовок авторизации удаляется из запроса, и поскольку я не могу добавить метод Bearer к NSURLCredentialStorage
, он не может пройти аутентификацию после перенаправления.
Что было бы хорошим решением? Я могу только подумать, чтобы поймать перенаправление и изменить NSURLRequest
, поэтому он включает заголовок Bearer
. Но как?
Ответы
Ответ 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) {
//
}];
Обновление
Использовать клиент Oauth2 для AFNetworking, написанный матом
https://github.com/AFNetworking/AFOAuth2Client
Ответ 3
Если вы столкнулись с этой проблемой с инфраструктурой Django rest и маршрутизаторами, проблема может быть связана с завершающим косой чертой, сжимаемой NSUrlRequest. если завершающая косая черта обрезается, тогда django придется перенаправить ваш запрос, чтобы избежать этого, вы можете использовать Trailing_slash = True, как этот
router = routers.DefaultRouter(trailing_slash=False)
Таким образом, ваш заголовок авторизации и ваши параметры не будут потеряны.
Надеюсь, что это немного сэкономит время.