Git Product home page Git Product logo

dart-google-oauth2-library's Introduction

google_oauth2_client

Build Status

Description

Dart library to use for Google OAuth2 authentication / Client-side flow

Usage/Installation

Go to Google APIs Console and:

  • Create a new Project,
  • Create a new Client ID for web applications in "API Access" - You should select the "APIS and AUTH > Credentials" left menu item in the new APIs console and click on the "Create new Client ID" button,
  • Set JavaScript origins to your server or for example http://127.0.0.1:3030/ for local testing in Dartium

Add this dependency to your pubspec.yaml

  dependencies:
    google_oauth2_client: '>=0.3.4'

Web applications

Import the library in your dart application

  import "package:google_oauth2_client/google_oauth2_browser.dart";

Initialize the library with your parameters

final auth = new GoogleOAuth2(
    "YOUR CLIENT ID HERE",
    ["scope1", "scope2", ...],
    tokenLoaded: oauthReady,
    autoLogin: <true/false>);

The oauthReady function (a function you must define) will be called once your app has a valid OAuth token to call the APIs. If you set autoLogin to true and the user has authorized the app in the past, this will happen automatically. Otherwise, you need to call auth.login() to trigger a confirmation dialog.

Once you have an access token you can use the following to send authenticated requests to the API.

var request = new HttpRequest();
request.onLoad.listen(...)
request.open(method, url);
request.setRequestHeader("Authorization", "${auth.token.type} ${auth.token.data}");
request.send();

Or you can use the authenticate method of the OAuth2 class that takes a request, refreshes the access token if necessary and returns a request with the headers set correctly.

var request = new HttpRequest();
request.onLoad.listen(...);
request.open(method, url);
auth.authenticate(request).then((request) => request.send());

If you have an access token already (f.e. by using the Chrome Extension Identity API) you can use the SimpleOAuth2 class instead, that also supports the authenticate method.

var auth = new SimpleOAuth2(myToken);
var request new HttpRequest();
request.onLoad.listen(...);
request.open(method, url);
auth.authenticate(request).then((request) => request.send());

See example/oauth_example.dart for example login and request.

Console applications

Import the library in your dart application

  import "package:google_oauth2_client/google_oauth2_console.dart";

Setup the identifier and secret by creating a Google Installed App client id in APIs Console

  String identifier = "YOUR IDENTIFIER HERE";
  String secret = "YOUR SECRET HERE";
  List scopes =   ["scope1", "scope2", ...];
  final auth = new OAuth2Console(identifier: identifier, secret: secret, scopes: scopes);

When making calls the OAuth2Console provides a widthClient method that will provide you with the http.Client which to make requests. This may change in the future, for now it handles if the client has not allowed access to this application. credentials are stored locally by default in a file named credentials.json. Also by default the application does not check googles certificates, a certificate is provided ca-certificates.crt. Place the certificate in the same folder as the application curl will check cert before executing.

  Future clientCallback(http.Client client) {
    var completer = new Completer();
    final url = "https://www.googleapis.com/plus/v1/people/me";
    client.get(url).then((http.Response response) {
      var data = JSON.parse(response.body);
      print("Logged in as ${data["displayName"]}");
    });
    return completer.future;
  };

  auth.withClient(clientCallback);

Example below, the user needs to open the link provided to allow for offline support of the application.

~/dart/dart-google-oauth2-library/example$ dart oauth_example_console.dart

Client needs your authorization for scopes [https://www.googleapis.com/auth/plus.me]
In a web browser, go to https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force&response_type=code&client_id=299615367852-n0kfup30mfj5emlclfgud9g76itapvk9.apps.googleusercontent.com&redirect_uri=http%3A%2F%2Flocalhost%3A60476&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fplus.me
Then click "Allow access".

Waiting for your authorization...
Authorization received, processing...
Successfully authorized.

Logged in as Adam Singer

Currently console oauth2 does not work on windows yet. Mac and Linux should work if curl is in your path. curl is being used for passing the auth token from the browser back to the application.

Disclaimer

No guarantees about the security or functionality of this libary

Licenses

Copyright (c) 2013-2014 Gerwin Sturm & Adam Singer

Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License

------------------------
Based on http://code.google.com/p/google-api-dart-client

Copyright 2012 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License

dart-google-oauth2-library's People

Contributors

adam-singer avatar alextekartik avatar damondouglas avatar enyo avatar jwren avatar kevmoo avatar mogeta avatar ozzieorca avatar scarygami avatar srawlins avatar tomen avatar vicb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

dart-google-oauth2-library's Issues

browser auth cause Failed assertion: line 11 pos 12: '_window != null' is not true.

Following code:

GoogleOAuth2 auth = new GoogleOAuth2(CLIENT_ID, [SCOPE]);
auth.login().then((t){

...
});

causes below in polymer app. Dartium 1.5.7

Uncaught Error: 'package:google_oauth2_client/src/browser/utils.dart': Failed assertion: line 11 pos 12: '_window != null' is not true.
Stack Trace:
#0 _WindowPoller._WindowPoller (package:google_oauth2_client/src/browser/utils.dart:11:12)
#1 GoogleOAuth2.login.completeByPromptingUser. (package:google_oauth2_client/src/browser/google_oauth2.dart:171:21)
#2 _rootRunUnary (dart:async/zone.dart:730)
#3 _RootZone.runUnary (dart:async/zone.dart:864)
#4 _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:488)
#5 _Future._propagateToListeners (dart:async/future_impl.dart:571)
#6 _Future._completeWithValue (dart:async/future_impl.dart:331)
#7 _Future._asyncComplete. (dart:async/future_impl.dart:393)
#8 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#9 _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#10 _handleMutation (dart:html:38346)

Exception: 'package:google_oauth2_client/src/browser/utils.dart': Failed assertion: line 11 pos 12: '_window != null' is not true.

Failed to load resource: the server responded with a status of 405 (Method Not Allowed) ?

I have create my client id (include Books and Contacts API, InitPoint = http://127.0.0.1:3030), and modify "oauth_example.dart" as the following code. But I got error message:
Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
https://www.google.com/m8/feeds/contacts/default/full
Failed to load resource: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:3030' is therefore not allowed access.
https://www.google.com/m8/feeds/contacts/default/full
XMLHttpRequest cannot load https://www.google.com/m8/feeds/contacts/default/full. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:3030' is therefore not allowed access.

......
void main() {
  // use your own Client ID from the API Console here
  final auth = new GoogleOAuth2(
      "THIS IS MY CLIENT ID",
      ["https://www.googleapis.com/auth/books", "https://www.google.com/m8/feeds" ]);

  ......
}

Future _oauthReady(Token token) {
  ......
  //final url = "https://www.googleapis.com/books/v1/volumes/zyTCAlFPjgYC";
  final url = "https://www.google.com/m8/feeds/contacts/default/full";
  ......
}

Make hop a dev dependency

It brings in a whole pile of stuff (most glaringly unit_test) that shouldn't end up in most apps.

Future already completed exception

With the code below, I get the following error when clicking the login button the second and subsequent times.

Breaking on exception: Bad state: Future already completed

Exception: Bad state: Future already completed
  _AsyncCompleter.completeError (dart:async/future_impl.dart:19:32)
  GoogleOAuth2._createFutureChannel.<anonymous closure> (package:google_oauth2_client/src/browser/googleoauth2.dart:62:42)
  _onMessage (package:google_oauth2_client/src/browser/proxy_callback.dart:51:14)

This occurs when I'm not logged in to start with. The first login click correctly (I think) returns an error and prints "Immediate login failed". However, any subsequent login clicks produce the "Future already completed" exception.

import "dart:html";
import "package:google_drive_v2_api/drive_v2_api_browser.dart" as drivelib;
import "package:google_drive_v2_api/drive_v2_api_client.dart" as client;
import "package:google_oauth2_client/google_oauth2_browser.dart";

final CLIENT_ID = "905334712652.apps.googleusercontent.com";
final SCOPES = [drivelib.Drive.DRIVE_FILE_SCOPE];

void main() {
  var loginButton = query("#login");

  loginButton.onClick.listen((Event e) {
    login();
  });
}

void login() {
  var auth = new GoogleOAuth2(CLIENT_ID, SCOPES);

  auth.login(immediate: true)
    .then((token) {
      print("Logged in already");
    })
    .catchError((e) {
      print("Immediate login failed");
    });
}

Missing support for "approval_prompt"

Currently, as seen the in the example, there is no way to "switch" to a different account after logout.
One basic option would be to support "approval_prompt": "force" in the _getAuthorizeUri (checked locally)

Add port option for "one-shot" authorization http server

At the moment, the http server that gets the OAuth authorisation uses a random port number (here is the line of code).

Unfortunately, Google's compute engine only gives you the possibility to allow a specific host with port number to use as OAuth redirect urls and no wildcards (or at least I haven't find another way of doing it).

So at the moment, I have to update the google compute engine settings, every time I want a new OAuth client to be authorised.

If you think that this is a valid feature request, I can do the implementation myself.
Pull request attached.

Authentication works in Dartium, but not when compiled with dart2js

I'm putting it here first, to see if it's a problem with the library itself, but I suspect it's a overall Dart2JS problem.

I should be seeing a separate widow prompting me to login if I've not already, followed by a OAuth app permission request. This works when I run it in Dartium, but when I use

pub serve

executing it in Google Chrome.

What I get instead is:

Uncaught Error: NullError: Cannot call "closed" on null js_primitives.dart:25
Stack Trace: 
TypeError: Cannot read property 'closed' of undefined
    at _DOMWindowCrossFrame.get$closed (http://localhost:8080/index.dart.js:7527:32)
    at dart.J.get$closed$x (http://localhost:8080/index.dart.js:8807:39)
    at _WindowPoller.poll$0 (http://localhost:8080/index.dart.js:8425:13)
    at GoogleOAuth2_login_completeByPromptingUser_closure.call$1 (http://localhost:8080/index.dart.js:8126:56)
    at dart._rootRunUnary (http://localhost:8080/index.dart.js:3249:16)
    at _Future__propagateToListeners_handleValueCallback.call$0 (http://localhost:8080/index.dart.js:3627:47)
    at dart._Future.static._Future__propagateToListeners (http://localhost:8080/index.dart.js:3531:131)
    at _Future._completeWithValue$1 (http://localhost:8080/index.dart.js:3390:9)
    at _Future__asyncComplete_closure0.call$0 (http://localhost:8080/index.dart.js:3609:19)
    at _AsyncCallbackEntry.callback$0 (http://localhost:8080/index.dart.js:3769:28)
 js_primitives.dart:25
microtask error TypeError: Cannot read property 'closed' of undefined
    at _DOMWindowCrossFrame.get$closed (http://localhost:8080/index.dart.js:7527:32)
    at dart.J.get$closed$x (http://localhost:8080/index.dart.js:8807:39)
    at _WindowPoller.poll$0 (http://localhost:8080/index.dart.js:8425:13)
    at GoogleOAuth2_login_completeByPromptingUser_closure.call$1 (http://localhost:8080/index.dart.js:8126:56)
    at dart._rootRunUnary (http://localhost:8080/index.dart.js:3249:16)
    at _Future__propagateToListeners_handleValueCallback.call$0 (http://localhost:8080/index.dart.js:3627:47)
    at dart._Future.static._Future__propagateToListeners (http://localhost:8080/index.dart.js:3531:131)
    at _Future._completeWithValue$1 (http://localhost:8080/index.dart.js:3390:9)
    at _Future__asyncComplete_closure0.call$0 (http://localhost:8080/index.dart.js:3609:19)
    at _AsyncCallbackEntry.callback$0 (http://localhost:8080/index.dart.js:3769:28) js_primitives.dart:25
microtask error stack trace: Error
    at dart.wrapException (http://localhost:8080/index.dart.js:1835:15)
    at _rootHandleUncaughtError__closure.call$0 (http://localhost:8080/index.dart.js:3995:15)
    at _AsyncCallbackEntry.callback$0 (http://localhost:8080/index.dart.js:3769:28)
    at dart._asyncRunCallbackLoop (http://localhost:8080/index.dart.js:3152:13)
    at _asyncRunCallback (http://localhost:8080/index.dart.js:3161:9)
    at TimerImpl_internalCallback0.call$0 (http://localhost:8080/index.dart.js:1640:23)
    at invokeClosure_closure.call$0 (http://localhost:8080/index.dart.js:2644:29)
    at _IsolateContext.eval$1 (http://localhost:8080/index.dart.js:1042:23)
    at dart._callInIsolate (http://localhost:8080/index.dart.js:728:26)
    at invokeClosure (http://localhost:8080/index.dart.js:1963:16) 

I'm using the following Dart developer env

Dart Editor version 1.4.0.dev_02_02 (DEV)
Dart SDK version 1.4.0-dev.2.2

I was getting a similar error on the previous version 1.3.

Here is the pubspec.yaml file

name: google_plus_component
description: A pub package
dependencies:
  browser: any
  google_oauth2_client: any

Here's enough of the offending code

import 'package:google_oauth2_client/google_oauth2_browser.dart';

auth() {
  GoogleOAuth2 auth = new GoogleOAuth2(
      "client_id",
      ["https://www.googleapis.com/auth/plus.login"]
  );

  auth.ensureAuthenticated();
}

Cant pub get

Probably related to #68
Pub get is looping in a lot of errors like this:

SLVR: | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | version 0.8.4 of oauth2 doesn't match >=0.9.0 <0.10.0:
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | google_oauth2_client 0.4.1 from hosted -> oauth2 >=0.9.0 <0.10.0 from hosted (oauth2)

Using dart:js and Google's javascript

Load this in the page :

<script type="text/javascript">
  // https://developers.google.com/+/web/share/interactive
  (function() {
    var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://apis.google.com/js/client:plusone.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })();
</script>

When using new GoogleOAuth2(client_id, scopes); and then login, I get the cryptic :

Uncaught TypeError: Cannot call method 'replace' of undefined
(anonymous function) cb=gapi.loaded_0:464
(anonymous function) cb=gapi.loaded_0:459
g cb=gapi.loaded_0:63
c

... which is in the js loaded by https://apis.google.com/js/client:plusone.js ?
A Dart call makes a js lib fail.
Is it just me ?

I have dart:js imported as well, as I'm trying down the road to :

context['gapi']['interactivepost'].callMethod('render', ['google_plus_boast', share_options]);

but I'm not even there yet. This issue has too much shadows for me, can anyone shine some light ?


google_oauth2_client: '>=0.2.18 <1.0.0'
Dartium Version 31.0.1650.48 custom (240209).

Simple OAuth2 class with manually set token

In additionen to BrowserOAuth implement a simple SimpleOAuth2 class where the token can be set manually. Reason is to allow using the client libraries even if you get the token another way, f.e. via Chrome.Identity API for extensions/packaged apps.
Both BrowserOAuth and SimpleOAuth should be extending a common abstract class OAuth2 which will be passed to the client library. Both need to implement an "authenticate" method which sets the correct headers of a HttpRequest. The browser client library uses this method.

A similar system could be added to the ConsoleOAuth.

Cannot resolve warnings.

I'm working off of m4_breaking_changes. In the Dart Editor, the analyzer doesn't return any warnings, but hop produces the following warnings:

analyze_libs - lib/google_oauth2_console.dart: /dart-google-oauth2-library/lib/src/console/oauth2_console_client/oauth2.dart:226:28: no such named parameter "request_visible_actions" defined
                                                  225:           Uri.parse('http://localhost:${server.port}'),
                                                  226:           scopes: _scopes, request_visible_actions: _request_visible_actions);
                                                                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
analyze_libs - lib/google_oauth2_console.dart: /dart-google-oauth2-library/lib/src/console/oauth2_console_client/http.dart:56:41: cannot resolve tokenEndpoint in library oauth2
                                                   55:       var tokenRequest = urisEqual(
                                                   56:           streamedResponse.request.url, oauth2.tokenEndpoint);
                                                                                               ~~~~~~~~~~~~~~~~~~~~
analyze_libs - lib/google_oauth2_console.dart: /dart-google-oauth2-library/lib/src/console/oauth2_console_client/http.dart:56:41: expression does not yield a value
                                                   55:       var tokenRequest = urisEqual(
                                                   56:           streamedResponse.request.url, oauth2.tokenEndpoint);
                                                                                               ~~~~~~
analyze_libs: WARNING - lib/google_oauth2_console.dart
analyze_libs: PASSED: 1, WARNING: 1, ERROR: 0

Error in r22072

'package:google_oauth2_client/src/browser/utils.dart': Error: line 55 pos 19: type 'Uint32Array' is not loaded
final ary = new Uint32Array(1);
^
malformed type used.

Logout should send sign-out request

Currently, the logout() method simply deletes the stored token. It should send a sign-out request, otherwise a page using autoLogin: true will re-login immediately.

expose Token on server

I want to login to google on the client then send the token to my server and validate it there. i.e. I'm supporting logging into my app with a google account but no immediate plans to access google services on the server beyond validating the token.

Currently the Token class is in the browser part of the api which has a dependency on dart:html.

I don't see any obvious dependencies that the Token class has on dart:html

Login dialog pops open for a split second when token already present

Logging in while entering the credentials works as expected. Next i log out and log in again while the credentials are locally present, the login dialog pops open and disappears instantly. That is not expected. The dialog could appear if multiple google accounts could be chosen from. See #40.

Crash in IE 10

After compiling to JS and running in IE 10 I get an excepetion with
crypto.getRandomValues(ary)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.