Как отправить пароль со специальными символами из приложения на веб-сервер по NSURLConnection - PullRequest
0 голосов
/ 18 февраля 2019

Я должен войти в систему через свой веб-сервер. Все работает нормально, но не сгенерированные пароли, как |% <"> {} ¥ ^ ~. Как я должен кодировать пароли, как это?

Я создаю пользователя с паролем = |% <"> {} ¥ ^ ~ doset work (например, пароль типа« user1234 »работает отлично)

NSString *userName = self.usernameOutlet.text;
NSString *userPassword = self.passwordOutlet.text;
NSString *escapedString = [self.passwordOutlet.text stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
userPassword = escapedString;
NSString *post = [NSString stringWithFormat:@"login=%@&password=%@",userName,userPassword];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"http://XXXXXXXX/login"]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];

с паролями типа« user1234 »Я получаю cookie

с паролями типа "|% <"> {} ¥ ^ ~ "Я не получаю cookie

что я делаю не так?

1 Ответ

0 голосов
/ 18 февраля 2019

Заманчиво хотеть использовать URLQueryAllowedCharacterSet, но это не сработает для всех строк.Примечательно, что & и + пройдут без спасения.

Если вам интересно, почему мы должны в процентах экранировать & и +, то это потому, что эти два символа имеют особое значение в запросах x-www-form-urlencoded.& используется для разделения пар ключ-значение в запросе x-www-form-urlencoded, поэтому он усекает ваш пароль.И большинство веб-сервисов переводят + в пробел, так что вы также захотите избежать этого.

Итак, давайте сначала определим набор символов, который будет работать:

// NSCharacterSet+URLQueryValueAllowed.h

@interface NSCharacterSet (URLQueryValueAllowed)

@property (class, readonly, copy) NSCharacterSet *URLQueryValueAllowedCharacterSet;

@end

и

// NSCharacterSet+URLQueryValueAllowed.m

@implementation NSCharacterSet (URLQueryValueAllowed)

+ (NSCharacterSet *)URLQueryValueAllowedCharacterSet {
    static dispatch_once_t onceToken;
    static NSCharacterSet *queryValueAllowed;
    dispatch_once(&onceToken, ^{
        NSMutableCharacterSet *allowed = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
        NSString *generalDelimitersToEncode = @":#[]@";   // does not include "?" or "/" due to RFC 3986 - Section 3.4
        NSString *subDelimitersToEncode = @"!$&'()*+,;=";

        [allowed removeCharactersInString:generalDelimitersToEncode];
        [allowed removeCharactersInString:subDelimitersToEncode];

        queryValueAllowed = [allowed copy];
    });
    return queryValueAllowed;
}

@end

Затем, чтобы упростить нам жизнь, давайте определим NSDictionary категория для процентного кодирования словаря:

// NSDictionary+PercentEncoded.h

@interface NSDictionary (PercentEncoded)
- (NSString *)percentEncodedString;
- (NSData *)percentEncodedData;
@end

и

// NSDictionary+PercentEncoded.m

@implementation NSDictionary (PercentEncoded)
- (NSString *)percentEncodedString {
    NSMutableArray<NSString *> *results = [NSMutableArray array];
    NSCharacterSet *allowed = [NSCharacterSet URLQueryValueAllowedCharacterSet];

    for (NSString *key in self.allKeys) {
        NSString *encodedKey = [key stringByAddingPercentEncodingWithAllowedCharacters:allowed];
        NSString *value = [[self objectForKey:key] description];
        NSString *encodedValue = [value stringByAddingPercentEncodingWithAllowedCharacters:allowed];
        [results addObject:[NSString stringWithFormat:@"%@=%@", encodedKey, encodedValue]];
    }
    return [results componentsJoinedByString:@"&"];
}

- (NSData *)percentEncodedData {
    return [[self percentEncodedString] dataUsingEncoding:NSUTF8StringEncoding];
}
@end

Тогда ваш код приложения может сделать:

NSDictionary *dictionary = @{@"login": userName, @"password": userPassword};
NSData *body = [dictionary percentEncodedData];
...