Search code examples
actionscript-3apache-flexgoogle-plusflexbuilderflex4.6

How to integrate google+ in a flex mobile application


Anybody know how can integrate google+ in a flex mobile application. While i tried to authenticate with google+ getting an error like text="Error #2032: Stream Error. URL: https://accounts.google.com/o/oauth2/auth?response%5Ftype=code&redirect%5Furi=urn%3Aietf%3Awg%3Aoauth%3A2%2E0%3Aoob&client%5Fid ..." errorID=2032]. URL: https://accounts.google.com/o/oauth2/auth.


Solution

  • It's your lucky day, because I know how to do it :-)

    The doc is Using OAuth 2.0 for Installed Applications and you get the access token from the web page title.

    Below is my View and a screenshot of my app and the Google+ API console:

    enter image description here

    enter image description here

    <?xml version="1.0" encoding="utf-8"?>
    <s:View xmlns:fx="http://ns.adobe.com/mxml/2009" 
            xmlns:s="library://ns.adobe.com/flex/spark" 
            viewActivate="openSWV(event)"
            viewDeactivate="closeSWV(event)"
            title="Getting data...">
    
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
    
        <fx:Script>
            <![CDATA[
                import flash.media.StageWebView;
    
                private static const APP_ID:String     = 'XXXXXXXXX.apps.googleusercontent.com';
                private static const APP_SECRET:String = 'XXXXXXXXXXXXXXXXXXX';
                private static const APP_URL:String    = 'urn:ietf:wg:oauth:2.0:oob';
                private static const AUTH_URL:String   = 'https://accounts.google.com/o/oauth2/auth?';
    
                private var _swv:StageWebView = new StageWebView();
    
                private function openSWV(event:ViewNavigatorEvent):void {
                    _swv.addEventListener(Event.COMPLETE, extractAccessToken);
                    _swv.addEventListener(LocationChangeEvent.LOCATION_CHANGE, extractAccessToken);
                    _swv.addEventListener(IOErrorEvent.IO_ERROR, closeSWV);
                    _swv.addEventListener(ErrorEvent.ERROR, closeSWV);
                    stage.addEventListener(Event.RESIZE, resizeSWV);
    
                    _swv.stage = stage;
                    resizeSWV();
    
                    var reqVars:URLVariables = new URLVariables();
                    reqVars.client_id     = APP_ID;
                    reqVars.response_type = 'code';
                    reqVars.redirect_uri  = APP_URL;
                    reqVars.state         = getTimer();
                    reqVars.scope         = 'https://www.googleapis.com/auth/userinfo.profile';
                    _swv.loadURL(AUTH_URL + reqVars);
                }
    
                private function closeSWV(event:Event=null):void {
                    stage.removeEventListener(Event.RESIZE, resizeSWV);
                    if (! _swv)
                        return;
                    _swv.removeEventListener(Event.COMPLETE, extractAccessToken);
                    _swv.removeEventListener(LocationChangeEvent.LOCATION_CHANGE, extractAccessToken);
                    _swv.removeEventListener(IOErrorEvent.IO_ERROR, closeSWV);
                    _swv.removeEventListener(ErrorEvent.ERROR, closeSWV);
                    _swv.dispose();
                    _swv = null;
                }           
    
                private function resizeSWV(event:Event=null):void {
                    if (! _swv)
                        return;
                    // align to the right-bottom corner
                    _swv.viewPort = new Rectangle(stage.stageWidth - width, stage.stageHeight - height, width, height);
                }
    
                private function extractAccessToken(event:Event):void {
                    trace('title: ' + _swv.title);
                    trace('location: ' + _swv.location);
    
                    var code:String = getValue('code=', _swv.title);
                    if (code) {
                        trace('code=' + code);
    
                        closeSWV();
    
                        var reqVars:URLVariables = new URLVariables();
                        reqVars.code          = code;
                        reqVars.grant_type    = 'authorization_code';
                        reqVars.client_id     = APP_ID;
                        reqVars.client_secret = APP_SECRET;
                        reqVars.redirect_uri  = APP_URL;
    
                        var req:URLRequest = new URLRequest('https://accounts.google.com/o/oauth2/token');
                        req.method = URLRequestMethod.POST;
                        req.data = reqVars;
    
                        var loader:URLLoader = new URLLoader();
                        loader.addEventListener(Event.COMPLETE, handleComplete); 
                        loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handleError);
                        loader.addEventListener(IOErrorEvent.IO_ERROR, handleError);
                        loader.load(req);
                    }
                }
    
                private function handleError(event:ErrorEvent):void {
                    var loader:URLLoader = URLLoader(event.target); 
                    trace(event.text);
                    trace(loader.data);
                }
    
                private function handleComplete(event:Event):void {
                    var obj:Object;
                    var loader:URLLoader = URLLoader(event.target); 
                    trace(loader.data);
                    try {
                        obj = JSON.decode(loader.data);
                    } catch(e:Error) {
                        trace('Invalid JSON: ' + loader.data);
                        return;
                    }
    
                    trace('access_token=' + obj.access_token);
    
                    var req:URLRequest = new URLRequest('https://www.googleapis.com/oauth2/v1/userinfo?access_token=' + obj.access_token);
                    var loader2:URLLoader = new URLLoader();
                    loader2.addEventListener(Event.COMPLETE, handleComplete2); 
                    loader2.addEventListener(SecurityErrorEvent.SECURITY_ERROR, handleError);
                    loader2.addEventListener(IOErrorEvent.IO_ERROR, handleError);
                    loader2.load(req);
                }
    
                private function handleComplete2(event:Event):void {
                    var obj:Object;
                    var loader:URLLoader = URLLoader(event.target); 
                    trace(loader.data);
                    try {
                        obj = JSON.decode(loader.data);
                    } catch(e:Error) {
                        trace('Invalid JSON: ' + loader.data);
                        return;
                    }
                    var info:Object =  { 
                        ID:      obj.id,
                        FIRST:   obj.given_name,
                        LAST:    obj.family_name,
                        FEMALE:  (obj.gender != 'male'),
                        AVATAR:  obj.picture
                    };
    
                    _userid.text = 'id: '     + info['ID'];
                    _first.text  = 'first: '  + info['FIRST'];
                    _last.text   = 'last: '   + info['LAST'];
                    _female.text = 'female: ' + info['FEMALE'];
                    _avatar.text = 'avatar: ' + info['AVATAR'];
                    _img.source  = info['AVATAR'];
    
                    title = 'Your data';
                    _busy.visible = false;
                    _busy.includeInLayout = false;
                    _group.visible = true;
                }
    
                private function getValue(key:String, str:String):String {
                    const pattern:RegExp = /[-_a-zA-Z0-9\/.]+/;
                    var index:int = str.indexOf(key);
                    if (index > -1) {
                        var matches:Array = str.substring(index + key.length).match(pattern);
                        if (matches.length > 0)
                            return matches[0];
                    }
                    return null;
                }
            ]]>
        </fx:Script>
    
        <s:BusyIndicator id="_busy"/>
        <s:VGroup id="_group" visible="false">
        <s:Button id="_play" label="Start game"/>
            <s:Label id="_token"/>
            <s:Label id="_userid"/>
            <s:Label id="_first"/>
            <s:Label id="_last"/>
            <s:Label id="_female"/>
            <s:Label id="_avatar"/>
            <s:Image id="_img"/>
        </s:VGroup>
    </s:View>