Как отобразить проблему аутентификации в UIWebView?
Я пытаюсь получить доступ к безопасному веб-сайту через UIWebView. Когда я получаю доступ к нему через Safari, я получаю вызов аутентификации, но тот же не появляется в моем UIWebView в приложении. Как я могу заставить его появиться?
Любые указатели, примеры кода или ссылки будут очень полезны. Большое спасибо.
5 ответов
Это на самом деле очень просто... Я уверен, что вы можете просто показать UIAlertView, когда отображается делегат вызова аутентификации (или перед загрузкой URL, если вы точно знаете, что URL, который вы нажимаете, будет запрашивать информацию для авторизации входа в систему).). В любом случае, дело в том, чтобы создать свой собственный NSURLConnection
и я делаю некоторую логику, чтобы сохранить, был ли использован делегат аутентификации.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
{
NSLog(@"Did start loading: %@ auth:%d", [[request URL] absoluteString], _authed);
if (!_authed) {
_authed = NO;
/* pretty sure i'm leaking here, leave me alone... i just happen to leak sometimes */
[[NSURLConnection alloc] initWithRequest:request delegate:self];
return NO;
}
return YES;
}
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
{
NSLog(@"got auth challange");
if ([challenge previousFailureCount] == 0) {
_authed = YES;
/* SET YOUR credentials, i'm just hard coding them in, tweak as necessary */
[[challenge sender] useCredential:[NSURLCredential credentialWithUser:@"username" password:@"password" persistence:NSURLCredentialPersistencePermanent] forAuthenticationChallenge:challenge];
} else {
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response;
{
NSLog(@"received response via nsurlconnection");
/** THIS IS WHERE YOU SET MAKE THE NEW REQUEST TO UIWebView, which will use the new saved auth info **/
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:]];
[_webView loadRequest:urlRequest];
}
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection *)connection;
{
return NO;
}
Вы также можете предоставить свои учетные данные в URL. Просто добавьте имя пользователя и пароль между "http://" и "page url".
NSString *urlString = @"http://username:password@domain.com/home";
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]];
Как вы знаете, UIWebView не предоставляет возможности для связи с сервером. Я решил эту проблему следующим образом: в методе делегата mustStartLoadWithRequest из UIWebView я инициировал еще одно соединение с NSURLConnection, и уже в методе делегата NSURLConnection didReceiveAuthenticationChallenge обработал запрос с сервера. А в методе didReceiveResponse (если вызов пришел) затем снова в том же UIWebView загрузить тот же URL (вызов уже обработан:). Не забудьте отменить соединение в didReceiveResponse, иначе это удвоит трафик.
Если вы испытываете симптомы того, что Зак описал в комментариях к ответу Сахила:
как сказал y5h, добавьте `_authed = YES'в метод didReceiveResponse, который остановит бесконечный цикл. даже если аутентификация не прошла успешно, вам нужно обработать ее так, как если бы она была аутентифицирована, поэтому она попытается продолжить загрузку страницы, если аутентификация не требуется, если аутентификация действительно требовалась, тогда она просто не будет работать, как обычно.
для второго признака, где shouldStartLoadWithRequest: срабатывает несколько раз (из-за встроенного содержимого на веб-странице), и он просто покажет последнюю загруженную вещь, а не всю веб-страницу, сделайте это:
в mustStartLoadWithRequest: метод, добавьте это к вершине
if(webview.loading){ //if url requests come through while its loading, its probably embedded content
return YES;
}
редактировать: этот метод имеет проблемы, если страница полностью загружается, а затем загружает больше встроенного содержимого, разрывается с Facebook, что является единственным случаем, который я видел до сих пор
это пропустит URL-адреса, пока веб-сайт пытается загрузить. Я не уверен, безопасно ли предполагать, что каждый URL после первоначального запроса является встроенным содержимым, но для моих целей это, похоже, сработало, так что, возможно, это будет и для вас.
также используйте
- (void) connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
так как
connection:canAuthenticateAgainstProtectionSpace:
connection:didReciveAuthenticationChallenge:
connection:didCancelAuthenticationChallenge:
изгнаны, и для меня, вы не могли пройти аутентификацию на веб-сайтах https, используя их
Я хотел бы предложить другой ответ, используя следующий модуль: https://github.com/jivesoftware/JiveAuthenticatingHTTPProtocol
Он содержит пример, показывающий, как использовать UIAlertView
запрашивать пароль у пользователя и может быть легко адаптирован для возврата сохраненного пароля, например, из локальной БД.
Отказ от ответственности: я никоим образом не связан с Jive, и никогда не был, это всего лишь предложение инструмента, который помог мне после нескольких дней борьбы с этим.