Не удается получить токен доступа от OAuth Google API для установленных приложений

Я создаю поток аутентификации OAuth, чтобы пользователи моего установленного приложения могли получить доступ к своим личным электронным таблицам Google. Я кодирую с помощью Adobe ExtendScript, поэтому я не могу использовать клиентские библиотеки Javascript, которые предоставляет Google. Я несколько раз читал документацию Google OAuth 2.0 для установленных приложений, но мне нужна помощь. с одним аспектом потока OAuth. Я могу получить код авторизации, запустив браузер из установленного приложения и попросив пользователя отправить свои учетные данные, а затем скопировать и вставить код авторизации обратно в приложение. Однако, когда я отправляю POST на конечную точку для обмена кода авторизации на токен доступа, это не работает. В теле ответа от Google показано следующее:

Moved Temporarily
The document has moved <A HREF="https://accounts.google.com/o/oauth2/token">here</A>.

И все же я сделал POST-вызов на тот же самый URL, что и в теге href. Итак, я не уверен, почему Google сказал мне, что конечная точка временно переместилась, когда я отправил POST на тот же URL. Вот код, который я использую для создания POST.

function getAccessToken(authcode)
{
    var http = require('http'),
        OAuthAccessEndPoint = 'https://accounts.google.com/o/oauth2/token',
        OAuthAccessParams = {};

    OAuthAccessParams['code']             = authcode;
    OAuthAccessParams['client_id']        = '{my_client_id}';
    OAuthAccessParams['client_secret']    = '{my_client_secret}';
    OAuthAccessParams['redirect_uri']     = 'urn:ietf:wg:oauth:2.0:oob';
    OAuthAccessParams['grant_type']       = 'authorization_code';

    var response = http.post(OAuthAccessEndPoint, OAuthAccessParams);

}

Сообщение оформлено нормально, но кто-нибудь знает, почему в ответе Google появилось сообщение «Временно перемещено»? Любые предложения очень ценятся!

РЕДАКТИРОВАТЬ: Чтобы уточнить, вот запрос, который мой скрипт делает в необработанном виде:

POST /o/oauth2/token HTTP/1.1
User-Agent: Adobe ExtendScript
Accept: */*
Connection: close
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 226

code={authcode}&client_id={my_client_id}&client_secret={my_client_secret}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code&

Если я использую код авторизации в cURL вместе с другими параметрами, я получаю успешный ответ от серверов OAuth Google. Итак, очевидно, что что-то не так с тем, как мои сокеты взаимодействуют с конечными точками Google, но я не уверен, что именно. Возможно ли, что одни компоненты нуждаются в кодировке URI, а другие нет? Вот cURL, который я использую:

#!/bin/bash
AUTHCODE="$1"

POSTCONTENT="code=$AUTHCODE&client_id={my_client_id}&client_secret={my_client_secret}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code&"

echo $POSTCONTENT

curl -v --data $POSTCONTENT https://accounts.google.com/o/oauth2/token

РЕДАКТИРОВАТЬ 2: Итак, поскольку сокеты не поддерживают SSL в Extendscript, я написал функцию, которая использует вызовы уровня ОС для вызова запроса. Если в OSX мы можем предположить, что у нас есть доступ к cURL, но в Windows мы должны написать VBScript, который запускается через хост cscript в командной строке. Для ExtendScript вот функция, которая делает веб-запрос:

function webRequest(method, endpoint, query){

    var response = null,
        wincurl  = WORKING_DIR.fsName + '\\lib\\curl.vbs',
        curlCmd = '';

    try {

        if ( os() == "Win" ) {
            curlCmd = 'cscript "' + wincurl + '" /Method:' + method + ' /URL:' + endpoint + ' /Query:' + query + ' //nologo';
        } else {
            if (method === "POST") {
                curlCmd = 'curl -s -d "' + query + '" ' + endpoint;
            } else if (method === "GET") {
                curlCmd = 'curl -s -G -d "' + query + '" ' + endpoint;
            }
        }

        response = system.callSystem(curlCmd);

    } catch (err) {

        alert("Error\nUnable to make a `"+ method +"` request to the network endpoint.  Please try again.");

    }

    return response;

}

function os(){
    var os = system.osName;
    if (!os.length) { os = $.os; }
    app_os =  ( os.indexOf("Win") != -1 )  ?  "Win" : "Mac";
    return app_os;
}

А вот скрипт VBScript, который вызывается из библиотеки ExtendScript. Требуется три параметра, все строки:

set namedArgs = WScript.Arguments.Named

sMethod = namedArgs.Item("Method")
sUrl = namedArgs.Item("URL")
sRequest = namedArgs.Item("Query")

HTTPPost sMethod, sUrl, sRequest

Function HTTPPost(sMethod, sUrl, sRequest)

    set oHTTP = CreateObject("Microsoft.XMLHTTP")  

    If sMethod = "POST" Then
        oHTTP.open "POST", sUrl,false
    ElseIf sMethod = "GET" Then
        oHTTP.open "GET", sUrl,false
    End If

    oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
    oHTTP.setRequestHeader "Content-Length", Len(sRequest)
    oHTTP.send sRequest

    HTTPPost = oHTTP.responseText

    WScript.Echo HTTPPost

End Function 

Вы можете использовать это в ExtendScript для любой конечной точки API, но ответ всегда будет строкой. Итак, в случае конечных точек Google OAuth вы получите строку, которая выглядит как JSON. Итак, вам нужно будет проанализировать его с помощью чего-то вроде JSON.parse ().


person ariestav    schedule 04.09.2013    source источник
comment
Также попытался обернуть все значения, используемые в объекте запроса, с помощью encodeURIComponent (). Те же результаты.   -  person ariestav    schedule 04.09.2013
comment
Я не знаю extendscript, но вы можете увидеть что-то подобное, если случайно отправили запрос по http, а не по https. Да, я вижу https в вашем URL-адресе, но на некоторых языках вам нужно предоставить дополнительный аргумент библиотеке http, чтобы она выполняла https.   -  person Tim Bray    schedule 04.09.2013
comment
@Tim Спасибо за предложение. Я буду смотреть в него.   -  person ariestav    schedule 04.09.2013
comment
Что ж, ExtendScript основан на Javascript, а конкретная библиотека, которую я использую, использует объект Socket для установления сетевого взаимодействия. Есть ли у объекта Socket свойство / метод, которые обеспечат безопасную передачу данных по https?   -  person ariestav    schedule 05.09.2013
comment
@TimBray Что ж, ваша догадка насчет http и https была верной. Согласно этому сообщению на сайте Adobe (forum.adobe.com/message/3500864#3500864 ), собственный объект Socket в ExtendScript не поддерживает SSL. Мне нужно будет разработать другой метод доступа к SSL из ExtendScript. Спасибо!   -  person ariestav    schedule 05.09.2013
comment
Могу я предложить вам, возможно, создать веб-службу или выполнить сценарий VB, который будет действовать как мост между вами и Google?   -  person Eric B.    schedule 09.09.2013
comment
Да, я это сделал. . . вы можете увидеть решение здесь: forum.adobe.com/message/5663858#5663858 но я обновлю свой ответ и здесь.   -  person ariestav    schedule 09.09.2013


Ответы (1)


См. Правки выше для ответа на этот вопрос. По сути, это сводилось к тому, что объекты Socket в ExtendScript не поддерживали SSL. В приведенном выше решении показан обходной путь с использованием метода ExtendScript system.callSystem () для доступа к cURL в OSX и VBScript в Windows.

person ariestav    schedule 11.09.2013