2

任何人都知道如何将 google+ 集成到 flex 移动应用程序中。当我尝试使用 google+ 进行身份验证时,收到类似 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]。网址:https ://accounts.google.com/o/oauth2/auth 。

4

1 回答 1

2

这是你的幸运日,因为我知道该怎么做 :-)

该文档是Using OAuth 2.0 for Installed Applications并且您从网页标题中获取访问令牌。

下面是我的视图和我的应用程序和 Google+ API 控制台的屏幕截图:

在此处输入图像描述

在此处输入图像描述

<?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>
于 2012-05-24T07:27:44.983 回答