Skip to content

Facebook/Twitter Login Error - "this auth is already used" #1025

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
PatrickAdams opened this issue Mar 14, 2016 · 28 comments
Closed

Facebook/Twitter Login Error - "this auth is already used" #1025

PatrickAdams opened this issue Mar 14, 2016 · 28 comments
Assignees

Comments

@PatrickAdams
Copy link

I'm getting the same error when trying to log in with Twitter as well as with Facebook as specified in #313

I have my parse server set up as follows.

},
  oauth: {
   twitter: {
     consumer_key: "redacted",
     consumer_secret: "redacted"
   },
   facebook: {
     appIds: "redacted"
   }
  }
});
@flovilmart
Copy link
Contributor

Are you with any chance having anonymousUsers on the client??

@PatrickAdams
Copy link
Author

Yes, I have anonymous users on, but I also thought they are on by default in Parse Server. The way I have it in my app is when a user first opens the app an anonymous user is created for them. The anonymous user is then transitioned to a regular user when they sign up. If they already have an account the anonymous user is deleted when they log in.

@flovilmart
Copy link
Contributor

Can you run your parse-server with the VERBOSE environment variable set to 1 (VERBOSE=1) so I can have a look at the login request that is failing?

Can you also post the code that you're using client side?

@PatrickAdams
Copy link
Author

Where do I set VERBOSE=1?

Also, do you want all of the client code I use for logging in with Twitter/FB?

@flovilmart
Copy link
Contributor

are you running parse-server locally or deployed somewhere?

@PatrickAdams
Copy link
Author

Heroku (this is my first time doing anything like this)

@flovilmart
Copy link
Contributor

@PatrickAdams
Copy link
Author

2016-03-14T19:59:08.961828+00:00 heroku[router]: at=info method=POST path="/parse/files/Image.jpg" host=redacted request_id=a075bcc2-22c6-4c91-80ab-357a28a908cc fwd="8.41.196.10" dyno=web.1 connect=1ms service=362ms status=201 bytes=691
2016-03-14T19:59:09.041377+00:00 app[web.1]: PUT /parse/classes/_User/gf9aoeSGeE { host: 'redacted',
2016-03-14T19:59:09.041416+00:00 app[web.1]:   'x-parse-os-version': '9.2 (15D21)',
2016-03-14T19:59:09.041421+00:00 app[web.1]:   'x-forwarded-for': '8.41.196.10',
2016-03-14T19:59:09.041433+00:00 app[web.1]:     }
2016-03-14T19:59:09.041418+00:00 app[web.1]:   'user-agent': 'RVWR/2 CFNetwork/758.2.8 Darwin/15.3.0',
2016-03-14T19:59:09.041427+00:00 app[web.1]:   "authData": {
2016-03-14T19:59:09.041431+00:00 app[web.1]:       "auth_token_secret": "redacted",
2016-03-14T19:59:09.041432+00:00 app[web.1]:       "consumer_secret": "redacted"
2016-03-14T19:59:09.041441+00:00 app[web.1]: }
2016-03-14T19:59:09.041387+00:00 app[web.1]:   connection: 'close',
2016-03-14T19:59:09.041438+00:00 app[web.1]:   },
2016-03-14T19:59:09.041388+00:00 app[web.1]:   'x-parse-client-version': 'i1.12.0',
2016-03-14T19:59:09.041426+00:00 app[web.1]:   "website": "http://rvwr.io",
2016-03-14T19:59:09.041428+00:00 app[web.1]:     "twitter": {
2016-03-14T19:59:09.041429+00:00 app[web.1]:       "auth_token": "redacted",
2016-03-14T19:59:09.041429+00:00 app[web.1]:       "id": "redacted",
2016-03-14T19:59:09.041430+00:00 app[web.1]:       "screen_name": "RVWRapp",
2016-03-14T19:59:09.041431+00:00 app[web.1]:       "consumer_key": "redacted",
2016-03-14T19:59:09.041434+00:00 app[web.1]:   "twitterID": "redacted",
2016-03-14T19:59:09.041388+00:00 app[web.1]:   accept: '*/*',
2016-03-14T19:59:09.041419+00:00 app[web.1]:   'x-parse-app-build-version': '2',
2016-03-14T19:59:09.041420+00:00 app[web.1]:   'x-request-id': '1279ed8c-640c-4169-8a1a-e7ea1891a687',
2016-03-14T19:59:09.041422+00:00 app[web.1]:   'x-forwarded-port': '443',
2016-03-14T19:59:09.041423+00:00 app[web.1]:   'connect-time': '2',
2016-03-14T19:59:09.041425+00:00 app[web.1]:   'content-length': '722' } {
2016-03-14T19:59:09.041426+00:00 app[web.1]:   "location": "Philadelphia, PA",
2016-03-14T19:59:09.224253+00:00 app[web.1]: error: ParseError { code: 208, message: 'this auth is already used' }
2016-03-14T19:59:09.041389+00:00 app[web.1]:   'x-parse-session-token': 'r:79df5bfdb6c56c1bd6c5a19717b5309c',
2016-03-14T19:59:09.041435+00:00 app[web.1]:   "anonymous": false,
2016-03-14T19:59:09.041437+00:00 app[web.1]:     "url": "https://xxx.s3.amazonaws.com/ec228f9bad159210dd0e3bce0e1b01de_Image.jpg",
2016-03-14T19:59:09.041412+00:00 app[web.1]:   'x-parse-application-id': 'Ct0jeEhOo1dLl8Rf7w6WbhNp7hllcUtkpmZTwAma',
2016-03-14T19:59:09.041417+00:00 app[web.1]:   'accept-encoding': 'gzip, deflate',
2016-03-14T19:59:09.041422+00:00 app[web.1]:   'x-forwarded-proto': 'https',
2016-03-14T19:59:09.041425+00:00 app[web.1]:   'total-route-time': '0',
2016-03-14T19:59:09.041440+00:00 app[web.1]:   "name": "RVWR"
2016-03-14T19:59:09.041414+00:00 app[web.1]:   'x-parse-client-key': '1c0ZIRZ1xSj6nVkow5uyfs7h5yHqgTn8XTBYplH0',
2016-03-14T19:59:09.041420+00:00 app[web.1]:   'x-parse-app-display-version': '1.2.1',
2016-03-14T19:59:09.041436+00:00 app[web.1]:     "__type": "File",
2016-03-14T19:59:09.041438+00:00 app[web.1]:     "name": "ec228f9bad159210dd0e3bce0e1b01de_Image.jpg"
2016-03-14T19:59:09.041414+00:00 app[web.1]:   'x-parse-installation-id': 'ca5e628e-444a-4186-aed7-a3bb9d1128a7',
2016-03-14T19:59:09.041417+00:00 app[web.1]:   'accept-language': 'en-us',
2016-03-14T19:59:09.041423+00:00 app[web.1]:   via: '1.1 vaguer'
2016-03-14T19:59:09.041424+00:00 app[web.1]:   'x-request-start': '1457985549030',
2016-03-14T19:59:09.041434+00:00 app[web.1]:   },
2016-03-14T19:59:09.041436+00:00 app[web.1]:   "image": {
2016-03-14T19:59:09.041418+00:00 app[web.1]:   'content-type': 'application/json; charset=utf-8',
2016-03-14T19:59:09.041439+00:00 app[web.1]:   "about": "An iOS app for reviewing...everything. More information here: https://t.co/nWUYj3q7T0 Created by @patrickleeadams.",
2016-03-14T19:59:09.226634+00:00 heroku[router]: at=info method=PUT path="/parse/classes/_User/redacted" host=redacted request_id=1279ed8c-640c-4169-8a1a-e7ea1891a687 fwd="8.41.196.10" dyno=web.1 connect=2ms service=191ms status=400 bytes=524
```,

@PatrickAdams
Copy link
Author

- (void)loginWithTwitter:(void (^)(BOOL succeeded, BOOL isNew, NSError *error, NSArray *twitterIDs, NSString *username))completionHandler
{
    NSMutableArray *twitterIDsArray = [[NSMutableArray alloc] init];
    [PFTwitterUtils logInWithBlock:^(PFUser *user, NSError *error) {
        if (!user) {
            completionHandler(NO, NO, error, nil, nil);
        } else if(user.isNew) {
            NSString *requestString = [NSString stringWithFormat:@"https://api.twitter.com/1.1/account/verify_credentials.json"];
            NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:requestString]];
            [[PFTwitterUtils twitter] signRequest:request];

            [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                if (!data) {
                    completionHandler(NO, YES, error, nil, nil);
                    return;
                }

                NSDictionary* result = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
                if (!result) {
                    completionHandler(NO, YES, error, nil, nil);
                    return;
                }

                if (![result[@"name"] isEqualToString:@""]) {
                    user[@"name"] = result[@"name"];
                }
                if (![result[@"description"] isEqualToString:@""]) {
                    user[@"about"] = result[@"description"];
                }
                if (![result[@"location"] isEqualToString:@""]) {
                    user[@"location"] = result[@"location"];
                }
                if (result[@"entities"][@"url"][@"urls"][0][@"expanded_url"] != nil) {
                    user[@"website"] = result[@"entities"][@"url"][@"urls"][0][@"expanded_url"];
                }
                if (![[result[@"id"] stringValue] isEqualToString:@""]) {
                    user[@"twitterID"] = [result[@"id"] stringValue];
                }

                NSString *usernameString;
                if (![result[@"screen_name"] isEqualToString:@""]) {
                    usernameString = result[@"screen_name"];
                }

                NSURL *pictureURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@", result[@"profile_image_url_https"]]];
                NSData *imageData = [NSData dataWithContentsOfURL:pictureURL];
                PFFile *imageFile = [PFFile fileWithName:@"Image.jpg" data:imageData];
                user[@"image"] = imageFile;
                user[@"anonymous"] = [NSNumber numberWithBool:NO];

                [self resultFromtwitterRequestWithURLString:@"https://api.twitter.com/1.1/friends/ids.json" andCompletion:^(NSDictionary *result, NSError *error) {
                    NSDictionary *twitterIDs = result;
                    for (NSNumber *identifier in twitterIDs[@"ids"]) {
                        [twitterIDsArray addObject:[NSString stringWithFormat:@"%@", identifier]];
                    }
                }];

                [user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
                    completionHandler(succeeded, YES, error, twitterIDsArray, usernameString);
                }];
            }] resume];
        } else {
            completionHandler(YES, NO, error, nil, nil);
        }
    }];
}

@flovilmart
Copy link
Contributor

That's what I thought, the request that's being sent is a PUT on the user, so it tries to link the current user (that is anonymous) with the twitter user that it finds. It can't link it as the objectId's don't match.

@nlutsenko I just had a look with the iOS SDK: https://github.com/ParsePlatform/Parse-SDK-iOS-OSX/blob/749a46f1663772272e75cfa195b5732827d8d2fa/Parse/Internal/User/AuthenticationProviders/Controller/PFUserAuthenticationController.m#L116

I see here that when the currentUser is anonymous, the login method will try to link the user instead of doing a proper 'login'. How should we handle that server side?

EDIT: I now see that it tries to login upon unsuccessful attempt to link.

@flovilmart
Copy link
Contributor

similar to #996

@flovilmart
Copy link
Contributor

@PatrickAdams any chance in the logs just after the PUT /parse/classes/_User/:userid there is a POST /parses/classes/_User ?

@PatrickAdams
Copy link
Author

No, from what I can tell there is no POST after the PUT.

@flovilmart
Copy link
Contributor

The SDK is supposedly sending it when you have anonymous users enabled.

@PatrickAdams
Copy link
Author

Is there anything I can do now or do I just need to wait for a fix?

@flovilmart
Copy link
Contributor

I'm really not sure about that problem, that's what bothering me...

@flovilmart
Copy link
Contributor

@PatrickAdams can you try the branch associated with that PR: #1081

@PatrickAdams
Copy link
Author

@flovilmart I set up my project using parse-server-example so in that case will parse-server stay up to date with master? Also, how would I test out your PR? I don't actually have parse-server cloned, just the example project.

@flovilmart
Copy link
Contributor

so, if you're using parse-server-example:

git submodule add https://github.com/parseplatform/parse-server
npm link parse-server ./parse-server
cd parse-server
git fetch
git checkout flovilmart.deleteAuthData
# then start the server

@nlutsenko nlutsenko assigned flovilmart and unassigned nlutsenko Mar 17, 2016
@PatrickAdams
Copy link
Author

@flovilmart was your branch merged? I don't see it anymore.

@flovilmart
Copy link
Contributor

yes it's been merged, you can use master then

@PatrickAdams
Copy link
Author

@flovilmart it seems to have fixed the issue!

@flovilmart
Copy link
Contributor

Nice! Do you confirm that with VERBOSE=1 you have a proper POST after the failed PUT?

@PatrickAdams
Copy link
Author

yes.

@flovilmart
Copy link
Contributor

YAY! nice!! Such a stupid bug... Anyhow, I'll close it now, if the error occurs again, please reopen!

@andrey-krukovskiy
Copy link

andrey-krukovskiy commented Aug 2, 2016

Hi!
Seems, I have experienced the same issue with parse-server 2.2.17 and Parse-iOS-SDK built from master when trying to authenticate existing user via twitter.
Here logs from heroku:

2016-08-02T11:22:38.512030+00:00 heroku[router]: at=info method=POST path="/parse/users" host=myapp.herokuapp.com request_id=be8bc098-7613-4537-9361-eb6b6ffae8ec fwd="134.17.26.86" dyno=web.1 connect=1ms service=90ms status=400 bytes=576
2016-08-02T11:22:38.426412+00:00 app[web.1]: verbose: REQUEST for [POST] /parse/users: {
2016-08-02T11:22:38.426430+00:00 app[web.1]:   "authData": {
2016-08-02T11:22:38.426431+00:00 app[web.1]:     "twitter": {
2016-08-02T11:22:38.426433+00:00 app[web.1]:       "auth_token": "xxx",
2016-08-02T11:22:38.426434+00:00 app[web.1]:       "id": "xxx",
2016-08-02T11:22:38.426435+00:00 app[web.1]:       "screen_name": "xxx",
2016-08-02T11:22:38.426436+00:00 app[web.1]:       "auth_token_secret": "xxx",
2016-08-02T11:22:38.426436+00:00 app[web.1]:       "consumer_key": "xxx",
2016-08-02T11:22:38.426437+00:00 app[web.1]:       "consumer_secret": "xxx"
2016-08-02T11:22:38.426438+00:00 app[web.1]:     }
2016-08-02T11:22:38.426438+00:00 app[web.1]:   }
2016-08-02T11:22:38.426440+00:00 app[web.1]: } method=POST, url=/parse/users, host=myapp.herokuapp.com, connection=close, x-parse-client-version=i1.14.2, accept=*/*, x-parse-application-id=ChedayApp, x-parse-installation-id=183e75c1-053d-4f35-bad1-b32dd4eed5f0, accept-encoding=gzip, deflate, x-parse-os-version=9.3 (15G31), accept-language=en-us, content-type=application/json; charset=utf-8, user-agent=Myapp/1 CFNetwork/758.3.15 Darwin/15.6.0, x-parse-app-build-version=1, x-parse-app-display-version=1.0, x-request-id=be8bc098-7613-4537-9361-eb6b6ffae8ec, x-forwarded-for=134.17.26.86, x-forwarded-proto=https, x-forwarded-port=443, via=1.1 vegur, connect-time=1, x-request-start=1470136958419, total-route-time=0, content-length=323, auth_token=xxx, id=xxx, screen_name=xxx, auth_token_secret=xxx, consumer_key=xxx, consumer_secret=xxx
2016-08-02T11:22:38.508202+00:00 app[web.1]: error: Error generating response. ParseError { code: 208, message: 'this auth is already used' } code=208, message=this auth is already used
2016-08-02T11:22:38.510666+00:00 app[web.1]: [object Object]

UPD:
Seems, I somehow get duplicated user in database. Probably this can happen when perform two quick requests to the parse server.

@flovilmart
Copy link
Contributor

@andrey-krukovskiy sorry for the late response. Did you manage to isolate the race condition? Can you confirm this is 2 concurrent requests that makes it fail (with the logs)

@andrey-krukovskiy
Copy link

@flovilmart No, I did not. Cannot reproduce it now on parse-server 2.2.18

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants