django-allauth logging in with Facebook token from iOS Device

前端 未结 2 791
轻奢々
轻奢々 2021-02-02 01:43

I am using the Facebook iOS SDK to POST the Facebook Access Token to my Django server URI. The corresponding views.py function is shown below and I get a 200 Response code when

2条回答
  •  再見小時候
    2021-02-02 02:05

    Thanks for all the help and input -- I finally solved it. I don't know the exact root cause of why logging in with Facebook munged the cookies and standard login worked fine. I did notice that the domain of the cookies returned from the Facebook login were formatted with a leading "." like this:

    [ .domain.com ]
    

    Whereas the standard login that worked had cookie domains like this:

    [ www.domain.com ]
    

    I parsed the cookies from the HTTP response after successfully logging in with Facebook and stored them in the singleton:

                    // Extract cookie information
                    NSRange range = [cookieString rangeOfString:@"csrftoken="];
                    if (range.location!=NSNotFound){
                        cookieString = [cookieString substringFromIndex:NSMaxRange(range)];
                        range = [cookieString rangeOfString:@";"];
                        if (range.location!=NSNotFound){
                            self.appDelegate.djangoCsrftoken = [cookieString substringToIndex:range.location];
                        }
                    }
                    range = [cookieString rangeOfString:@"sessionid="];
                    if (range.location!=NSNotFound){
                        cookieString = [cookieString substringFromIndex:NSMaxRange(range)];
                        range = [cookieString rangeOfString:@";"];
                        if (range.location!=NSNotFound){
                            self.appDelegate.djangoSessionId = [cookieString substringToIndex:range.location];
                        }
                    }
    
                    if (LOGIN_DEBUG) { // Debug the response
                        NSLog(@"Extracted csrftoken is: %@",self.appDelegate.djangoCsrftoken);
                        NSLog(@"Extracted sessionid is: %@",self.appDelegate.djangoSessionId);
                    }
    

    I then, created those cookies explicitly for the following request:

        // Clear all cookies when app launches
        NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
        for (NSHTTPCookie *each in cookieStorage.cookies) {
            //if ( [each.domain isEqualToString:DOMAIN] ) {
            NSLog(@"Deleting cookie: %@ -- %@",each.name,each.domain);
            [cookieStorage deleteCookie:each];
            //}
        }
    
        //////////////// CSRF TOKEN /////////////////////
    
        // Create cookies based on parsed values
        NSMutableDictionary *cookieCsrfProperties = [NSMutableDictionary dictionary];
        [cookieCsrfProperties setObject:@"csrftoken" forKey:NSHTTPCookieName];
        [cookieCsrfProperties setObject:self.appDelegate.djangoCsrftoken forKey:NSHTTPCookieValue];
        [cookieCsrfProperties setObject:DOMAIN forKey:NSHTTPCookieDomain];
        [cookieCsrfProperties setObject:DOMAIN forKey:NSHTTPCookieOriginURL];
        [cookieCsrfProperties setObject:@"/" forKey:NSHTTPCookiePath];
        [cookieCsrfProperties setObject:@"0" forKey:NSHTTPCookieVersion];
    
        // Set expiration to one month from now or any NSDate of your choosing
        // this makes the cookie sessionless and it will persist across web sessions and app launches
        /// if you want the cookie to be destroyed when your app exits, don't set this
        [cookieCsrfProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];
    
        NSHTTPCookie *csrfCookie = [NSHTTPCookie cookieWithProperties:cookieCsrfProperties];
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:csrfCookie];
    
        //////////////// SessionId TOKEN /////////////////////
    
        // Create cookies based on parsed values
        NSMutableDictionary *cookieSessionIdProperties = [NSMutableDictionary dictionary];
        [cookieSessionIdProperties setObject:@"sessionid" forKey:NSHTTPCookieName];
        [cookieSessionIdProperties setObject:self.appDelegate.djangoSessionId forKey:NSHTTPCookieValue];
        [cookieSessionIdProperties setObject:DOMAIN forKey:NSHTTPCookieDomain];
        [cookieSessionIdProperties setObject:DOMAIN forKey:NSHTTPCookieOriginURL];
        [cookieSessionIdProperties setObject:@"/" forKey:NSHTTPCookiePath];
        [cookieSessionIdProperties setObject:@"0" forKey:NSHTTPCookieVersion];
    
        // Set expiration to one month from now or any NSDate of your choosing
        // this makes the cookie sessionless and it will persist across web sessions and app launches
        /// if you want the cookie to be destroyed when your app exits, don't set this
        [cookieCsrfProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires];
    
        NSHTTPCookie *sessionIdCookie = [NSHTTPCookie cookieWithProperties:cookieSessionIdProperties];
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:sessionIdCookie];
    
        ///////////////////////////////////////////////////
    
        // Create request
        NSURL *url = [NSURL URLWithString:requestUrl];
        NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];
        urlRequest.HTTPShouldHandleCookies = YES;
    
        NSHTTPCookie *setCookie;
        for (setCookie in [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies) {
            if ( ([setCookie.name isEqualToString:@"csrftoken" ] || [setCookie.name isEqualToString:@"sessionid"]) ) {
                NSLog(@"Adding Cookie: %@ = %@  [ %@ ]", setCookie.name, setCookie.value, setCookie.domain);
                [urlRequest addValue:setCookie.value forHTTPHeaderField:setCookie.name];
            }
        }
        NSURLResponse *response = nil;
        NSError * error = nil;
        NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
    

    After doing that, I could successfully login with Facebook using Django-allauth.

提交回复
热议问题