2013-07-09 10 views
1

Я пытаюсь узнать, как использовать службу quickblox для моего брандмауэра приложения iphone. Однако я столкнулся с проблемой при проверке подключения моего приложения к службе quickblox. Чтобы авторизовать соединение, мне нужно получить токен из quickblox, отправив почтовый запрос, содержащий идентификатор моего приложения, auth_key, timestamp, nonce и подпись. Однако, когда я отправляю почтовый запрос, сервер отвечает с кодом состояния 422, что моя подпись недействительна. Подпись создается с помощью идентификатора приложения, ключа auth, timestamp и nonce и создания хэша hmac-sha1. Я подтвердил, что мой генератор hmac-sha1 работает правильно, поэтому я не знаю, ошибочен ли мой почтовый код или что-то другое, потому что он всегда возвращается с ошибкой сигнатуры. Вот мой делегат приложения:Неверная подпись Ошибка при отправке запроса авторизации на quickblox через сообщение xml

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    int nonce = arc4random() % (999999999 - 100000) + 100000; 
    int timestamp = [[NSDate date] timeIntervalSince1970]; 

    NSString *prehash = [NSString stringWithFormat:@"application_id=999&auth_key=999999999999999&timestamp=%i&nonce=%i", timestamp, nonce]; 


    HashSHA256 * hashSHA256 = [[HashSHA256 alloc] init]; 
    NSString * hash = [hashSHA256 hashedValue:prehash]; 

    NSLog(@"%@", hash); 


    [application setIdleTimerDisabled:YES]; 

    // 
    // Set QuickBlox credentials. Register at admin.quickblox.com, create a new app 
    // and copy credentials here to have your own backend instance enabled. 
    [QBSettings setApplicationID:9999]; 
    [QBSettings setAuthorizationKey:@"999999999999999"]; 
    [QBSettings setAuthorizationSecret:@"111111111111111"]; 

    NSString *urlString = [NSString stringWithFormat:@"http://api.quickblox.com/session.xml"]; 
    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; 
    [request setURL:[NSURL URLWithString:urlString]]; 
    [request setHTTPMethod:@"POST"]; 


    //set headers 
    NSString *contentType = [NSString stringWithFormat:@"0.1.0"]; 
    [request addValue:contentType forHTTPHeaderField: @"QuickBlox-REST-API-Version:"]; 

    //create the body 
    NSMutableData *postBody = [NSMutableData data]; 
    [postBody appendData:[[NSString stringWithFormat:@"application_id=9999&auth_key=999999999999999&timestamp=%i&nonce=%i&signature=%@", timestamp, nonce, hash] dataUsingEncoding:NSUTF8StringEncoding]]; 

    //post request 
    [request setHTTPBody:postBody]; 

    NSString *a = [[NSString alloc] initWithData:postBody encoding:NSUTF8StringEncoding]; 
    NSLog(@"%@", a); 

    //get response 
    NSHTTPURLResponse* urlResponse = nil; 
    NSError *error = [[NSError alloc] init]; 
    NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error]; 
    NSString *result = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
    NSLog(@"Response Code: %d", [urlResponse statusCode]); 
    if ([urlResponse statusCode] >= 200 && [urlResponse statusCode] < 500) { 
     NSLog(@"Response: %@", result); 

     //here you get the response 

    } 


    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; 
    self.window.backgroundColor = [UIColor whiteColor]; 

    // Show Splash screen 
    // 
    SplashViewController *splashViewController = [[SplashViewController alloc] init]; 
    [self.window setRootViewController:splashViewController]; 
    [splashViewController release]; 

    [self.window makeKeyAndVisible]; 

    return YES; 
} 

В документации говорится, что запрос должен быть отформатирован следующим образом. Кто-нибудь видит проблему с почтовым запросом, не правильно ли ее форматирование? В документации говорится, что ее следует отформатировать следующим образом:

curl -X POST \ 
-H "QuickBlox-REST-API-Version: 0.1.0" \ 
-d "application_id=140&auth_key=7quWEh-k6TqghXe&timestamp=1326964049&nonce=414546828&signature=e6e603c251a569e70a2f27a8c71b5017e81e05d5" \ 
https://api.quickblox.com/session.xml //sent to this address 

Заранее благодарен.

ответ

1

Похоже, вы пропустили свой auth_secret. Он должен использоваться при создании подписи. Вот пример python, он может быть вам полезен.

import time, random, hmac, urllib, httplib 
from hashlib import sha1 

nonce = str(random.randint(1, 10000)) 
timestamp = str(int(time.time())) 

signature_raw_body = ("application_id=" + application_id + "&auth_key=" + auth_key + 
      "&nonce=" + nonce + "&timestamp=" + timestamp) 

signature = hmac.new(auth_secret, signature_raw_body, sha1).hexdigest() 

params = urllib.urlencode({'application_id': application_id, 
          'auth_key': auth_key, 
          'timestamp': timestamp, 'nonce' : nonce, 
          'signature' : signature}) 

conn = httplib.HTTPSConnection("api.quickblox.com") 
conn.request("POST", "/session", params, {}) 
response = conn.getresponse() 

Также вы можете использовать этот метод для создания подписи:

+ (NSString *)signData:(NSData *)data withSecret:(NSString *)secret{ 
NSData *secretData = [secret dataUsingEncoding:NSUTF8StringEncoding]; 
NSData *clearTextData = data; 
uint8_t digest[CC_SHA1_DIGEST_LENGTH] = {0}; 
CCHmacContext hmacContext; 
CCHmacInit(&hmacContext, kCCHmacAlgSHA1, secretData.bytes, secretData.length); 
CCHmacUpdate(&hmacContext, clearTextData.bytes, clearTextData.length); 
CCHmacFinal(&hmacContext, digest); 
NSData *result = [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH]; 
NSString *hash = [result description]; 
hash = [hash stringByReplacingOccurrencesOfString:@" " withString:@""]; 
hash = [hash stringByReplacingOccurrencesOfString:@"<" withString:@""]; 
hash = [hash stringByReplacingOccurrencesOfString:@">" withString:@""]; 

return hash; 
} 

Где:

#define CC_SHA1_DIGEST_LENGTH 20 

NSData * данные данные из сырого тела с помощью NSUTF8StringEncoding.

+0

Большое спасибо, я пытался это проработать уже несколько дней. Наконец ты помог мне исправить это. – user1615326

+1

Код Objective-C от Quickblox iOS SDK, поэтому, возможно, использование SDK будет лучшим решением. –

+1

hmac() не работает для меня. (Он говорит, что 'TypeError: 'module' object не является вызываемым') Должен ли он быть hmac.new()? – huggie