2013-01-05 2 views
5

iOS 6에서 AFOAuth2Client 및 AFNetworking을 사용하여 액세스 토큰을 얻을 수는 있지만 리소스에 액세스 할 수 없으면 서버는 인증되지 않은 401 상태 코드로 응답합니다. 이는 OAuth 공급자로서 문지기를 사용하는 맞춤 레일스 3 API 백엔드에 대한 것입니다. 다음 클라이언트 루비 코드는 OAuth2를 보석을 사용하여 확인을 작동합니다AFOAuth2Client가 리소스에 액세스 할 수 없음

client = OAuth2::Client.new(app_id, secret, site: "http://subdomain.example.com/") 
access_token = client.password.get_token('username', 'password') 
access_token.get('/api/1/products').parsed 

아이폰 OS 코드 로그인 버튼 처리기에서 나는 사용자 이름과 암호를 사용하여 인증 및 자격 증명을 저장, 아래 :

- (IBAction)login:(id)sender { 
    NSString *username = [usernameField text]; 
    NSString *password = [passwordField text]; 

    NSURL *url = [NSURL URLWithString:kClientBaseURL]; 
    AFOAuth2Client *client = [AFOAuth2Client clientWithBaseURL:url clientID:kClientID secret:kClientSecret]; 

    [client authenticateUsingOAuthWithPath:@"oauth/token" 
           username:username 
           password:password 
           scope:nil 
           success:^(AFOAuthCredential *credential) { 
            NSLog(@"Successfully received OAuth credentials %@", credential.accessToken); 
            [AFOAuthCredential storeCredential:credential 
                 withIdentifier:client.serviceProviderIdentifier]; 
            [self performSegueWithIdentifier:@"LoginSegue" sender:sender]; 
           } 
           failure:^(NSError *error) { 
            NSLog(@"Error: %@", error); 
            [passwordField setText:@""]; 
           }]; 
} 

그리고 내 엔드 포인트에 대한 AFHTTPClient을 서브 클래스했고 initWithBaseURL에이 자격 증명을 검색하고 액세스 토큰과 함께 인증 헤더를 설정

- (id)initWithBaseURL:(NSURL *)url { 
    self = [super initWithBaseURL:url]; 
    if (!self) { 
     return nil; 
    } 

    [self registerHTTPOperationClass:[AFJSONRequestOperation class]]; 
    [self setDefaultHeader:@"Accept" value:@"application/json"]; 

    AFOAuthCredential *credential = [AFOAuthCredential retrieveCredentialWithIdentifier:@"subdomain.example.com"]; 
    [self setAuthorizationHeaderWithToken:credential.accessToken]; 

    return self; 
} 

AFOAuth2Client 및 AFNetworking을 사용하는 올바른 방법입니까? 왜 이것이 작동하지 않는가?

답변

5

을 변경하여이 작업을 얻을 관리 :

AFOAuthCredential *credential = [AFOAuthCredential retrieveCredentialWithIdentifier:@"subdomain.example.com"]; 
    [self setAuthorizationHeaderWithToken:credential.accessToken]; 

에 : 나는 AFOAuth2ClientAFHTTPClient의 서브 클래스 자체가 그렇게 할 수 있음을이었다 통지하지 못했다 무엇

AFOAuthCredential *credential = [AFOAuthCredential retrieveCredentialWithIdentifier:@"subdomain.example.com"]; 
    NSString *authValue = [NSString stringWithFormat:@"Bearer %@", credential.accessToken]; 
    [self setDefaultHeader:@"Authorization" value:authValue]; 

UPDATE

API 클래스의 기본 클래스로 사용됩니다. 예 :

@interface YFExampleAPIClient : AFOAuth2Client 

    + (YFExampleAPIClient *)sharedClient; 

    /** 

    */ 
    - (void)authenticateWithUsernameAndPassword:(NSString *)username 
             password:(NSString *)password 
             success:(void (^)(AFOAuthCredential *credential))success 
             failure:(void (^)(NSError *error))failure; 

    @end 

는 그리고 구현이된다 : initWithBaseURL가 HTTP 헤더를 허용 설정 오버라이드 (override)

@implementation YFExampleAPIClient 

+ (YFExampleAPIClient *)sharedClient { 
    static YFExampleAPIClient *_sharedClient = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     NSURL *url = [NSURL URLWithString:kClientBaseURL]; 
     _sharedClient = [YFExampleAPIClient clientWithBaseURL:url clientID:kClientID secret:kClientSecret]; 
    }); 

    return _sharedClient; 
} 

- (void)authenticateWithUsernameAndPassword:(NSString *)username 
            password:(NSString *)password 
            success:(void (^)(AFOAuthCredential *credential))success 
            failure:(void (^)(NSError *error))failure { 
    [self authenticateUsingOAuthWithPath:@"oauth/token" 
            username:username 
            password:password 
            scope:nil 
            success:^(AFOAuthCredential *credential) { 
             NSLog(@"Successfully received OAuth credentials %@", credential.accessToken); 
             [self setAuthorizationHeaderWithCredential:credential]; 
             success(credential); 
            } 
            failure:^(NSError *error) { 
             NSLog(@"Error: %@", error); 
             failure(error); 
            }]; 
} 

- (id)initWithBaseURL:(NSURL *)url 
      clientID:(NSString *)clientID 
       secret:(NSString *)secret { 
    self = [super initWithBaseURL:url clientID:clientID secret:secret]; 
    if (!self) { 
     return nil; 
    } 

    [self setDefaultHeader:@"Accept" value:@"application/json"]; 

    return self; 
} 

@end 

하는 것으로.

전체 소스 코드는 GitHub의에서 사용할 수 있습니다 -

+1

https://github.com/yellowfeather/rails-saas-ios는 https://github.com/AFNetworking/AFOAuth2Client/blob/master/AFOAuth2Client/AFOAuth2Client.h 파일을 살펴보십시오. 맨 위에는 기본 클래스로 사용하지 않는 것이 좋습니다. – davidbitton

관련 문제