2015-03-23 4 views
0

Я строю систему, которую люди могут аутентифицировать, чтобы читать их gmail. У меня это работает отлично на моем сайте, используя OAuth2 в Python; в ответе от google я получаю access_token, token_type, expires_in и (самое главное) refresh_token.Как получить Google refresh_token в Javascript API?

Теперь я хочу получить то же самое в Javascript (для приложения, которое я создаю, используя Ionic). Поэтому я использую ngCordovaOauth для проверки подлинности с помощью следующего кода:

$cordovaOauth.google(
    'xxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com', 
    ['https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/gmail.readonly'], 
    { 
     'access_type': 'offline', 
     'approval_prompt': 'force' 
    } 
) 
    .then(function(result){ 
     console.log("Response object -> " + JSON.stringify(result)); 
    }, function(error){ 
     console.log('Error -> ' + error); 
    }); 

Как и ожидалось, это производит следующий экран на моем телефоне:

enter image description here

Но в JSON я получаю обратно нет refresh_token :

{"access_token":"xxxx.xxxxxxxxxxxx","token_type":"Bearer","expires_in":"3599"} 

кто-нибудь знает, почему я не получаю refesh_token при использовании Javascr ipt api? Все советы приветствуются!

ответ

0

CordovaOauth использует Implicit grant type OAuth 2.0, который согласно спецификации предназначен для «клиентов, реализованных в браузере с использованием языка сценариев, такого как JavaScript». С помощью этого потока клиенту напрямую выдается токен доступа, и только это.

В Authorization Code grant type клиенту выдается авторизационный код, который затем обменивается на токены доступа и обновления, но это также включает в себя аутентификацию самого клиента, поэтому это делается с использованием типа «сервер-сервер» , Вы не захотите подвергать ваш client_id/client_secret конечный пользователь, обращенный к JavaScript-коду.

Также обратите внимание на Google Documentation, объясняющий различные сценарии.

+0

Благодарим вас за разъяснение. Так правильно ли я понимаю, что у меня нет способа получить refresh_token из моего Ionic/Angular-app? – kramer65

+0

Хотя я мало знаю об Ионе, связь с сервером будет необходима для использования типа гранта авторизации, который приведет к выдаче токена обновления (если требуется). Таким образом, чистое решение JavaScript, работающее в браузере пользователя, не будет выполнено. –

+0

Итак, вот моя новая идея: не используйте неявный тип гранта, чтобы я мог получить код авторизации в javascript. Затем я отправляю полученный код авторизации на свой сервер и использую свой сервер для получения токена доступа и токена обновления. Это имеет смысл для вас? – kramer65

0

Почему вы не можете запросить токен обновления с помощью Cordova/Ionic/Angular? ...

У меня есть приложение, которое получает обновления-маркер, доступ-маркер и т.д. Поэтому я использовал этот код:

apiKey     = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'; 
clientID    = 'xxxxxxxxxxxxxxxxxxxxxxxxxx2ivu3.apps.googleusercontent.com'; 
var notiID    = 0; 
var googleapi   = { 

authorize: function(options) { 
       var deferred = $.Deferred(); 
       var authUrl = 'https://accounts.google.com/o/oauth2/auth?' + $.param({ 
        client_id: options.client_id, 
        redirect_uri: options.redirect_uri, 
        response_type: 'code', 
        scope: options.scope 
       }); 

       var authWindow = window.open(authUrl, '_blank', 'location=yes'); 
       $(authWindow).on('loadstart', function(e) { 
        var url = e.originalEvent.url; 
        var code = /\?code=(.+)$/.exec(url); 
        var error = /\?error=(.+)$/.exec(url); 

        if (code || error) { 
         //Always close the browser when match is found 
         authWindow.close(); 
         loadingSpinner(); 
        } 

        if (code) { 
         $.post('https://accounts.google.com/o/oauth2/token', { 
          code: code[1], 
          client_id: options.client_id, 
          client_secret: options.client_secret, 
          redirect_uri: options.redirect_uri, 
          grant_type: 'authorization_code' 
         }).done(function(data) { 
          deferred.resolve(data); 

          $("#loginStatus").html('Name: ' + data.given_name); 
         }).fail(function(response) { 
          deferred.reject(response.responseJSON); 
         }); 
        } else if (error) { 
         deferred.reject({ 
          error: error[1] 
         }); 
        } 
       }); 

       return deferred.promise(); 
      } 
     }; 

И это один для запроса и обновить-доступ-токена:

function callGoogle() 
{ 

// alert('starting'); 
    googleapi.authorize({ 
         client_id: clientID, 
         client_secret: apiKey, 
         redirect_uri: 'http://localhost', 
         scope: 'https://www.googleapis.com/auth/analytics.readonly' 
         }).done(function(data) { 
           localStorage.accessToken=data.access_token; 
           localStorage.refreshToken=data.refresh_token; 
           // console.log(JSON.stringify(data)); 
           // console.log(localStorage.accessToken); 
           // console.log(localStorage.refreshToken); 
           getDataProfile(); 


           }); 

} 

Дайте мне попробовать и дайте мне знать, где вам нужна дальнейшая помощь. Для этого вам понадобится только плагин inappbrowser и console. Также конечно jQuery.

+0

Спасибо за ваш обширный ответ. Могу я спросить: безопасно ли предоставить apiKey и clientId в js-источнике приложения? – kramer65

+0

Посмотрите эту тему -> http://stackoverflow.com/questions/28276712/cordova-google-maps-api-key-safe-enough Должно быть достаточно информации для вас :-). – Sithys

+0

Извините, крамер, это была неправильная ссылка, которую я отправил, я имел в виду это - 3 дня назад -> http://stackoverflow.com/questions/29157626/how-to-secure-my-google-maps-javascript-v3- апи-ключ-в-ан-ионным-Cordova-приложение – Sithys

Смежные вопросы