FBWebDialogs缺少会话Cookie以验证用户

时间:2013-07-26 16:56:31

标签: ios facebook facebook-ios-sdk

我从我的服务器获取一个facebook令牌(它是从之前登录的另一台设备上存储的)。我正在使用它打开一个会话,然后我用

进行一个相对简单的调用
[FBWebDialogs presentRequestsDialogModallyWithSession:[FBSession activeSession]
                                                  message:@"Message"
                                                    title:@"Title"
                                               parameters:params
                                                  handler:^(FBWebDialogResult result,
                                                  NSURL *resultURL, NSError *error) {}}];

弹出的网页窗口显示“发生错误。请稍后重试。”。我单击OK然后触发回调(我在上面省略了)。当我跟踪resultURL时,我得到了

fbconnect://success?error_code=110&error_msg=Missing+user+cookie+%28to+validate+session+user%29

我可以使用会话在我的墙上发布就好了。我错过了什么?

3 个答案:

答案 0 :(得分:0)

我发现Facebook重新调整的令牌包含其他元数据,例如随后所有Web视图使用的c_user cookie。设置远程缓存系统时,必须在远程服务器上存储到期日期和刷新日期,并返回它们以便在TokenData对象中使用。如果没有正确完成,则不会设置正确的元数据。

答案 1 :(得分:0)

确保您在有效的Facebook会话中拥有“publish_actions”权限。

    bool hasPublishPermission = NO;
    for( NSString* permission in [FBSession.activeSession permissions] )
    {
        if( [permission isEqualToString:@"publish_actions"] )
        {
            hasPublishPermission = YES;
            break;
        }
    }
    if( !hasPublishPermission )
    {
        [FBSession openActiveSessionWithPublishPermissions:@[@"publish_actions"]
                                           defaultAudience:FBSessionDefaultAudienceFriends
                                              allowLoginUI:YES
                                         completionHandler:^(FBSession *session,
                                                             FBSessionState status,
                                                             NSError *error) {
                                             if( status==FBSessionStateOpen )
                                             {
                                                 //Present dialog
                                             }
                                         }];
    }
    else
    {
        //Present dialog
    }

另外,请确保已将“FacebookAppID”添加到项目的plist中。 (请参阅https://developers.facebook.com/docs/getting-started/facebook-sdk-for-ios/选项卡“配置新的Xcode项目”)这可能会导致您所描述的错误。

希望这有帮助

答案 2 :(得分:0)

我已经在我的应用中集成了嵌入式webview 与Facebook sdk 3.5.3

我希望我的代码会给你一些想法...

-(IBAction)fblogin:(id)sender{
         NSArray * arr=[NSArray                arrayWithObjects:@"publish_actions",@"email",@"basic_info",@"user_location",@"user_birthday",@"user_likes", nil];

        Interest_Status=[NSString stringWithFormat:@"%@",txt_interest.text];
            [FBSession  setActiveSession:session];

        if (FBSession.activeSession.isOpen) {
            if ([btn_Login.titleLabel.text isEqualToString:@"Logout"]) {

                [btn_Login setTitle:@"Login" forState:UIControlStateNormal];
                [btn_Login setImage:[UIImage imageNamed:@"FBLogin.png"] forState:UIControlStateNormal];


                FBSessionTokenCachingStrategy *tokenCachingStrategy = [[FBSessionTokenCachingStrategy alloc]
                                                                       initWithUserDefaultTokenInformationKeyName:nil];

                tokenCachingStrategy=nil;
                FBSession *seession=[FBSession activeSession];
                [seession closeAndClearTokenInformation];
                [session close];
                [FBSession setActiveSession:nil];
                session=nil;

                session=[[FBSession alloc]initWithPermissions:arr];
                self.ProfileLale.hidden=YES;


            }
            /*else if ([btn_Login.titleLabel.text isEqualToString:@"Login"]) {
                    [self updateForSessionChangeForSlot:1];
            }*/


        }else{
            [session openWithBehavior:FBSessionLoginBehaviorForcingWebView
                    completionHandler:^(FBSession *session,
                                        FBSessionState status,
                                        NSError *error) {
                            // this handler is called back whether the login succeeds or fails; in the
                            // success case it will also be called back upon each state transition between
                            // session-open and session-close
                        if (error)
                                {
                                    NSLog(@"error=%@ \n\n description=%@ \n\n,",error,error.description);
                                    [self switchToNoActiveUser];
                                }else{
                                    [self updateForSessionChangeForSlot:1];
                                }
                    }];

        }
 }




- (void)updateForSessionChangeForSlot:(int)slot {
   if (session.isOpen) {
                // fetch profile info such as name, id, etc. for the open session
                // Fetch user data
            FBRequest *me = [[FBRequest alloc] initWithSession:session
                                                     graphPath:@"me"];

            [me startWithCompletionHandler:^(FBRequestConnection *connection,
                                             NSDictionary<FBGraphUser> *user,
                                             NSError *error) {
                    // because we have a cached copy of the connection, we can check
                    // to see if this is the connection we care about; a prematurely
                    // cancelled connection will short-circuit here
                    //   if (me != self.pendingRequest) {
                    //      return;
                    //  }
                  NSLog(@"user=%@",user);

                    //  self.pendingRequest = nil;
                    //  self.pendingLoginForSlot = -1;

                    // we interpret an error in the initial fetch as a reason to
                    // fail the user switch, and leave the application without an
                    // active user (similar to initial state)
                if (error) {
                    NSLog(@"error=%@",error);
                    NSLog(@"Couldn't switch user: %@", error.localizedDescription);
                    [self switchToNoActiveUser];
                    return;
                }else{
                     NSLog(@"user=%@",user);
                     [btn_Login setTitle:@"Logout" forState:UIControlStateNormal];
                     [btn_Login setImage:[UIImage imageNamed:@"FBLogout.png"] forState:UIControlStateNormal];

                }
            }];

        } else {
                // in the closed case, we check to see if we picked up a cached token that we
                // expect to be valid and ready for use; if so then we open the session on the spot
            if (session.state == FBSessionStateCreatedTokenLoaded) {
                    // even though we had a cached token, we need to login to make the session usable
                [session openWithCompletionHandler:^(FBSession *session,
                                                     FBSessionState status,
                                                     NSError *error) {
                    [self updateForSessionChangeForSlot:slot];
                }];
            }
        }

  }



- (void)switchToNoActiveUser {

      /*UIAlertView *alter=[[UIAlertView alloc]initWithTitle:@"Message" message:@"No Internet connecton" delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
        [alter show];
       */
         NSArray * arr=[NSArray             arrayWithObjects:@"publish_actions",@"email",@"basic_info",@"user_location",@"user_birthday",@"user_likes", nil];

        session = nil;
        session=[[FBSession alloc]initWithPermissions:arr];
        [btn_Login setTitle:@"Login" forState:UIControlStateNormal];
        self.ProfileLale.hidden=YES;
        [btn_Login setImage:[UIImage imageNamed:@"FBLogin.png"] forState:UIControlStateNormal];

    }