Есть много способов сделать это. То, что я сделал, чтобы заставить Devise возвращать ошибки в мое приложение для iphone, которые я мог интерпретировать (например, 401), было создать специальное приложение для сбоя:
# config/initializers/devise.rb
config.warden do |manager|
manager.failure_app = CustomFailure
end
# config/initializers/custom_failure.rb
class CustomFailure < Devise::FailureApp
def respond
unless request.format.to_sym == :html
http_auth
else
super
end
end
end
В противном случае Devise просто возвращает HTML с кодом ответа перенаправления независимо от того, была ли введена правильная или неверная информация для входа.
Поскольку мое приложение требовало, чтобы пользователи проходили аутентификацию на моем рельсовом бэкэнде, я реализовал простую систему входа в систему, подобную этой:
#app/controllers/pages_controller.rb
before_filter :authenticate_user!, :only => [:login]
ssl_required :login # you have to set up ssl and ssl_requirement
def login
@user = current_user
respond_to do |format|
format.html {render :text => "#{@user.id}"}
format.xml {render :text => "#{@user.id}" }
end
end
#config/routes.rb
match '/login', :to => 'pages#login'
Затем в приложении iphone вы можете проверить, отправив запрос GET на / login следующим образом (я использую ASIHTTPRequest , потому что это круто):
- (void) validate_login:(NSString*)name :(NSString*)pwd
{
NSURL *login_url = [NSURL URLWithString:@"https://mysite.com/login"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:login_url];
[request setDelegate:self];
[request setUsername:name];
[request setPassword:pwd];
[request addRequestHeader:@"Accept" value:@"application/xml"];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
if ([request responseStatusCode] != 200) {
[self requestFailed:request];
}
else {
// authentication successful, store credentials
NSUSerDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults setValue:[request username] forKey:@"username"];
[defaults setValue:[request password] forKey:@"password"];
}
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSLog(@"failed with error: %d %@", [request responseStatusCode], [error localizedDescription]);
// tell user incorrect username/password
}
Тогда всякий раз, когда вам нужно опубликовать данные в приложении, вы можете извлечь имя пользователя и пароль из настроек пользователя по умолчанию и прикрепить их к запросу. Если вам нужно быть более защищенным, вы можете сохранить их в связке ключей.
Я уверен, что есть лучшие способы сделать это, но, надеюсь, это поможет вам задуматься о стратегиях аутентификации API.