Facebook Extended Permissions With Authorization by Overriding Class in swc

It may be not popular, but it is possible to substitute / override whole class from .swc file. Lets say you are using some public api, in our case Facebook actionscript api. I admire work of developer team, but I would like to have some things different. My facebook application requires publish_stream extended permission right after user login (authorize) my application. Even if official facebook api documentation says it is possible to ask for extended permission with login.php call (req_perms parameter), our facebook actionscript api does not offer setting this parameter.

After few moments of research it was clear that login.php call makes DesktopSession class, method onLogin()…

... some code ...

protected function onLogin(p_event:FacebookEvent):void {
	p_event.target.removeEventListener(FacebookEvent.COMPLETE, onLogin);
	
	if (p_event.success) {
		_auth_token = (p_event.data as StringResultData).value;
		
		//now that we have an auth_token we need the user to login with it
		var request:URLRequest = new URLRequest();
		var loginParams:String = '?';
		
		if (_offline_access) {
				loginParams += 'ext_perm=offline_access&';
		}
		
		request.url = login_url+loginParams+"api_key="+api_key+"&v="+api_version+"&auth_token="+_auth_token;
		
		navigateToURL(request, "_blank");
		
		_waiting_for_login = true;
		dispatchEvent(new FacebookEvent(FacebookEvent.WAITING_FOR_LOGIN));
	} else {
		onConnectionError(p_event.error);
	}
}

... some code ...

Now lets do the dirty work. If it were possible, I would extend DesktopSession class and override just onLogin function, but api creates and uses DesktopSession inside its whole logic, so there is no way to succeed. However, it is possible to override whole class. First, in your flex project (with facebook swc in library path), create directory structure com/facebook/session/ (the same as DesktopSession package defines), than copy DesktopSession.as file inside. Well, thats it 🙂 … From now, when you publish your application, compilator uses your DesktopSession instead of the one in .swc.

To make the new class working for my needs, onLogin function needs to be changed into something like this:

... some code ...

protected function onLogin(p_event:FacebookEvent):void {
	p_event.target.removeEventListener(FacebookEvent.COMPLETE, onLogin);
	
	if (p_event.success) {
		_auth_token = (p_event.data as StringResultData).value;
		
		//now that we have an auth_token we need the user to login with it
		var request:URLRequest = new URLRequest(login_url);
		var variables:URLVariables = new URLVariables();
		
		variables.req_perms = 'publish_stream';
		variables.api_key = api_key;
		variables.v = api_version;
		variables.auth_token = _auth_token;
		variables.fbconnect = "true";
		variables.connect_display = "page";
		
		request.data = variables;
		navigateToURL(request, "_blank");
		
		_waiting_for_login = true;
		dispatchEvent(new FacebookEvent(FacebookEvent.WAITING_FOR_LOGIN));
	} else {
		onConnectionError(p_event.error);
	}
}

... some code ...

By asking extended permissions with login.php, facebook opens more step authorization dialog where each permissions is separated into own step and user can allow or dont allow each.

Important:

  • Even if you send req_perms=publish_stream with login.php, facebook only accepts it when your app is live (not from your desktop testing) … Functionality already bugged in facebook bugzilla
  • Even if it is possible to override class this way, consider using it. Next time there may be newer version of .swc with some changes in your overriden class!

9 comments so far

  1. […] post connects my 3 previous posts: Flex IFrame – Web browser in flash, FacebookLogger and Facebook Extended Permissions With Authorization by Overriding Class in swc in order to create elegant solution for facebook connect with your desktop application (means […]

  2. Sharedtut February 3, 2010 16:16

    Great tutorial, thank you for putting all of this information together.

  3. […] Quelle, ich musste aber zwei Parameter entfernen, um es zum Laufen zu kriegen. […]

  4. Matt July 6, 2010 13:27

    I’ve got a question.. Is it possible to use this approach for a Websession too? It works for me at a Desktopsession but after publishing to my server it wont ask my extended permissions.

    Thanks
    Matt

  5. Jozef Chúťka July 7, 2010 10:04

    @Matt you can use DesktopSession with your live app, but if it is in iframe the flow is different. However this still works, I STRONGLY suggest to switch to the new Graph API, new permissions. please read:
    http://blog.yoz.sk/2010/05/facebook-graph-api-and-oauth-2-and-flash/

  6. Greg Steimann July 27, 2010 01:43

    Thanks for this! It’s really helpful! Though I noticed Facebook prompting me for “Invalid Next Url” after login. So I changed your code to include a “Next URL” in the variables and its been smooth sailing! Thanks again.

    Here’s my modified code for those interested (Note the addition of ‘variables.next = “http://www.facebook.com/connect/login_success.html”‘):

    protected function onLogin(p_event:FacebookEvent):void {
    p_event.target.removeEventListener(FacebookEvent.COMPLETE, onLogin);

    if (p_event.success) {
    _auth_token = (p_event.data as StringResultData).value;

    //now that we have an auth_token we need the user to login with it
    var request:URLRequest = new URLRequest(login_url);
    var variables:URLVariables = new URLVariables();

    variables.req_perms = ‘publish_stream’;
    variables.api_key = api_key;
    variables.v = api_version;
    variables.auth_token = _auth_token;
    variables.fbconnect = “true”;
    variables.connect_display = “page”;
    variables.next = “http://www.facebook.com/connect/login_success.html”
    request.data = variables;
    navigateToURL(request, “_blank”);

    _waiting_for_login = true;
    dispatchEvent(new FacebookEvent(FacebookEvent.WAITING_FOR_LOGIN));
    } else {
    onConnectionError(p_event.error);
    }
    }

  7. Jozef Chúťka July 27, 2010 09:29

    @Greg, thanks for your solution

  8. edap August 12, 2010 13:09

    great tutorial!
    but what if I want require more than one permission?
    publish_strem, email ecc…?

  9. Jozef Chúťka August 12, 2010 14:05

    hi @edap,
    you can join all permissions with “,” eg: “publish_stream,email” however this older article use facebook old rest api, I strongly recommend to use new graph api http://blog.yoz.sk/facebookoauthgraph/

Leave a comment

Please be polite and on topic. Your e-mail will never be published.