Coder Social home page Coder Social logo

dart-archive / googleapis_auth Goto Github PK

View Code? Open in Web Editor NEW
38.0 28.0 26.0 241 KB

Obtain OAuth 2.0 credentials to access Google APIs

Home Page: https://pub.dev/packages/googleapis_auth

License: BSD 3-Clause "New" or "Revised" License

Dart 89.19% JavaScript 10.81%

googleapis_auth's Introduction

googleapis_auth's People

Contributors

bcko avatar davidmorgan avatar galabar001 avatar jakobr-google avatar jonasfj avatar joshuaseaton avatar jpeiffer avatar jxson avatar kevmoo avatar michaelrfairhurst avatar mightyvoice avatar mkustermann avatar natebosch avatar nfdjps avatar nichite avatar scarygami avatar sgjesse avatar sigurdm avatar tvolkert 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  avatar  avatar  avatar

Watchers

 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

googleapis_auth's Issues

gapi.auth2 for client-side authentication flows

gapi.auth2 has been around for a while now and seems to be the preferred/future method for authenticating browser clients. Would be nice to upgrade this package to use it.

Biggest change is probably for Hybrid/Server-side flows, since those work differently with the new library.

Errors when using this library

When I remove this lib, these errors go away.

This is a brand new project

Can someone assist?

Thanks

Compiler message:
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/googleapis_auth-0.2.10/lib/src/oauth2_flows/implicit.dart:8:8: Error: Not found: 'dart:html'
import 'dart:html' as html;
       ^

/C:/flutter/.pub-cache/hosted/pub.dartlang.org/googleapis_auth-0.2.10/lib/src/oauth2_flows/implicit.dart:75:23: Error: Getter not found: 'context'.
        var gapi = js.context['gapi']['auth'];
                      ^^^^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/googleapis_auth-0.2.10/lib/src/oauth2_flows/implicit.dart:101:10: Error: Getter not found: 'document'.
    html.document.body.append(script);
         ^^^^^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/googleapis_auth-0.2.10/lib/src/oauth2_flows/implicit.dart:132:19: Error: Getter not found: 'context'.
    var gapi = js.context['gapi']['auth'];
                  ^^^^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/googleapis_auth-0.2.10/lib/src/oauth2_flows/implicit.dart:152:14: Error: Method not found: 'JsObject'.
      new js.JsObject.jsify(json),
             ^^^^^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/googleapis_auth-0.2.10/lib/src/oauth2_flows/implicit.dart:240:44: Error: Method not found: 'ScriptElement'.
  if (nonce == null) return () => new html.ScriptElement();
                                           ^^^^^^^^^^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/googleapis_auth-0.2.10/lib/src/oauth2_flows/implicit.dart:242:25: Error: Method not found: 'ScriptElement'.
  return () => new html.ScriptElement()..nonce = nonce;
                        ^^^^^^^^^^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/googleapis_auth-0.2.10/lib/src/oauth2_flows/implicit.dart:248:24: Error: 'Window' isn't a type.
String _getNonce({html.Window window}) {
                       ^^^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/googleapis_auth-0.2.10/lib/src/oauth2_flows/implicit.dart:249:40: Error: Getter not found: 'window'.
  final currentWindow = window ?? html.window;
                                       ^^^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/googleapis_auth-0.2.10/lib/src/oauth2_flows/implicit.dart:253:26: Error: 'HtmlElement' isn't a type.
        (element as html.HtmlElement).nonce ?? element.attributes['nonce'];
                         ^^^^^^^^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.0+4/lib/src/browser_client.dart:58:34: Error: 'Blob' isn't a type.
      var blob = xhr.response as Blob ?? Blob([]);
                                 ^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.0+4/lib/src/browser_client.dart:46:15: Error: The method 'HttpRequest' isn't defined for the class 'BrowserClient'.
 - 'BrowserClient' is from 'package:http/src/browser_client.dart' ('/C:/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.0+4/lib/src/browser_client.dart').
Try correcting the name to the name of an existing method, or defining a method named 'HttpRequest'.
    var xhr = HttpRequest();
              ^^^^^^^^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.0+4/lib/src/browser_client.dart:58:42: Error: The method 'Blob' isn't defined for the class 'BrowserClient'.
 - 'BrowserClient' is from 'package:http/src/browser_client.dart' ('/C:/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.0+4/lib/src/browser_client.dart').
Try correcting the name to the name of an existing method, or defining a method named 'Blob'.
      var blob = xhr.response as Blob ?? Blob([]);
                                         ^^^^
/C:/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.0+4/lib/src/browser_client.dart:59:20: Error: The method 'FileReader' isn't defined for the class 'BrowserClient'.
 - 'BrowserClient' is from 'package:http/src/browser_client.dart' ('/C:/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.0+4/lib/src/browser_client.dart').
Try correcting the name to the name of an existing method, or defining a method named 'FileReader'.
      var reader = FileReader();
                   ^^^^^^^^^^

My yaml file is as follows:

name: familiar_app
description: A new Flutter project.

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  rxdart: 0.23.1
  firebase_core: 0.4.4
  cloud_firestore: 0.13.0+1
  firebase_auth: 0.15.4
  cloud_functions: 0.4.1+9
  google_sign_in: 4.1.1
  googleapis_auth: 0.2.10

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter


# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  # assets:
  #  - images/a_dot_burr.jpeg
  #  - images/a_dot_ham.jpeg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.dev/assets-and-images/#resolution-aware.

  # For details regarding adding assets from package dependencies, see
  # https://flutter.dev/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.dev/custom-fonts/#from-packages

When using userconsent browser flow and trying to use with the PeopleApi package kicks out two errors

Steps to reproduce:

   return authBrowser
     .createImplicitBrowserFlow(_identifier, _googleScopes)
     .then((authBrowser.BrowserOAuth2Flow flow) {

       flow
         .clientViaUserConsent()
         .then((auth.AuthClient client) async {

            await new PeopleApi(client).people
             .get('people/me', personFields: 'coverPhotos,emailAddresses')
             .then( (Person person) {
                print(person);
        });

This looks like it actually does a network retrieve with the data in the response, but it kicks out two errors: Refused to set unsafe header "content-length", Refused to set unsafe header "user-agent";

RSAPrivateKey extraction failing when compiled to Javascript

The _extractRSAKeyFromDERBytes function in lib/src/crypto/pem.dart throws an unexpected error with RSA key parsing - but only when compiled to javascript.

A one-file .dart example of the issue

When run is dart native code, this 2048 bit length RSA key processes fine. But when compiled to javascript (say, to run in a cloud function with firebase), the following error comes up:

Uncaught Error: Invalid argument(s): Error while extracting private key from DER bytes: Invalid argument(s): The RSA modulus has a bit length of 31. Only 1024, 2048 and 4096 are supported.

Other keys I tried have a reported bit length of 28 or 29. All are 2048.

Not sure if this is an issue with dart2js or this library.

Support target audience

When setting a scope with target audience like this

final client = await clientViaServiceAccount(credentials, ['IAP_CLIENT_ID.apps.googleusercontent.com']);

JwtFlow.run() fails with

Exception: Unable to obtain credentials. Invalid response from server.
#0      JwtFlow.run (package:googleapis_auth/src/oauth2_flows/jwt.dart:89:7)
<asynchronous suspension>
#1      clientViaServiceAccount (package:googleapis_auth/auth_io.dart:200:30)

Since the response is structured like this

{
  "id_token": "<JWT_TOKEN>"
}

with missing fields like token_type, expires_in and access_token.

I can find no way of using target audience. Am I missing something?

can't seem to find a way to make this work on mobile

all i want is to login via youtube on my app. what am I missing?

`import 'dart:async';
import 'dart:convert' show json;

import 'package:googleapis_auth/auth_io.dart';
import "package:http/http.dart" as http;

import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:googleapis_auth/auth.dart';

class AuthService {
String oAuthClientId = 'HIDDEN';
var accountCredentials = new ServiceAccountCredentials.fromJson({
"private_key_id": "",
"private_key": "",
"client_email": "@developer.gserviceaccount.com",
"client_id": ".apps.googleusercontent.com",
"type": "service_account"
});
static List scopes = [
'email',
'https://www.googleapis.com/auth/youtube', // Youtube scope
];

final FirebaseAuth auth = FirebaseAuth.instance;
GoogleSignIn googleSignIn = GoogleSignIn(
scopes: scopes,
);

Future login() async {
final GoogleSignInAccount googleSignInAccount = await googleSignIn.signIn();
final GoogleSignInAuthentication googleSignInAuthentication = await googleSignInAccount.authentication;

final AuthCredential credential = GoogleAuthProvider.getCredential(
  accessToken: googleSignInAuthentication.accessToken,
  idToken: googleSignInAuthentication.idToken,
);

// You'll need this token to call the Youtube API. It expires every 30 minutes.
final token = googleSignInAuthentication.accessToken;

final AuthResult authResult = await auth.signInWithCredential(credential);
final FirebaseUser user = authResult.user;
assert(!user.isAnonymous);
assert(await user.getIdToken() != null);

final FirebaseUser currentUser = await auth.currentUser();
assert(user.uid == currentUser.uid);

var client = new http.Client();

obtainAccessCredentialsViaServiceAccount(accountCredentials, scopes, client)
    .then((AccessCredentials credentials) {
  // Access credentials are available in [credentials].
  // ...
  client.close();
});

return currentUser;

}

void signOut() {
auth.signOut();
googleSignIn.disconnect();
}

Future getUser() async{
final FirebaseUser user = await auth.currentUser();
return user;
}
}
`

clientViaToken support?

It could be possible to get an http_client via token?

Example, I use Chrome Extension Identity API

chrome.identity.getAuthToken().then((token) {
    clientViaToken(token).then((http_client) {
      var drive = new DriveApi(http_client);
      // ...
    });
});

Fails when used with dart2js under Firebase Functions

When used in code run under Firebase Functions (using firebase_functions_interop package), I get the error:
ReferenceError: XMLHttpRequest is not defined
when trying to call
obtainAccessCredentialsViaServiceAccount or clientViaServiceAccount

I tried adding polyfills using js interop and so on, but nothing seems to work

Failed host lookup: 'accounts.google.com'

I have written a flutter application that uses the package:googleapis_auth/auth_io.dart.

I have tested this with all combinations of
debug | release
Android | iOS
wifi | cellular

All combinations work except the release, Android, wifi. on this combination I am getting the following error:

[  +23 ms] E/flutter (25683): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: SocketException: Failed host lookup: 'accounts.google.com' (OS Error: No address associated with hostname, errno =
7)
[        ] E/flutter (25683): #0      IOClient.send (package:http/src/io_client.dart:33)
[        ] E/flutter (25683): <asynchronous suspension>
[        ] E/flutter (25683): #1      JwtFlow.run (package:googleapis_auth/src/oauth2_flows/jwt.dart:72)
[        ] E/flutter (25683): #2      clientViaServiceAccount (package:googleapis_auth/auth_io.dart:138)
[        ] E/flutter (25683): #3      _VideoLoadState.startLoading (package:yvfl/src/videoload.dart:109)

relavent code sections:

import 'package:googleapis/storage/v1.dart' as gcs;
import 'package:gcloud/storage.dart';
import 'package:googleapis_auth/auth_io.dart' as auth;
import 'package:connectivity/connectivity.dart';

final _credentials = new auth.ServiceAccountCredentials.fromJson({
      "type": "service_account",
      "private_key_id": "string",
      "private_key":
          "-----BEGIN PRIVATE KEY-----
            -----END PRIVATE KEY-----\n",
      "client_email": "string,
      "client_id": "string",
    });
    const _SCOPES = const [
      gcs.StorageApi.DevstorageReadOnlyScope
    ]; //read only is enough

    print('requesting remote bucket');
    try {
      auth.clientViaServiceAccount(_credentials, _SCOPES).then((client) async {
        final storage = Storage(client, 'webstorage-259216');
        final bucket = storage.bucket('bigwaveswvideo');
        //see if the file exists remotely
        ObjectInfo webInfo = await bucket.info(widget.movie);
        ...

The stack trace line package:yvfl/src/videoload.dart:109) is the source line auth.clientViaServiceAccount(_credentials, _SCOPES).then((client) async {.

refreshToken is missing sometimes.

Why do we have to have the refresh token here?
https://github.com/dart-lang/googleapis_auth/blob/master/lib/src/auth_http_utils.dart#L81

  AutoRefreshingClient(Client client, this.clientId, this.credentials,
      {bool closeUnderlyingClient: false})
      : super(client, closeUnderlyingClient: closeUnderlyingClient) {
    assert(credentials.refreshToken != null); //<--this
    authClient = authenticatedClient(baseClient, credentials);
  }

Here's what I'm doing:

  1. I'm getting an authenticated client with clientViaUserConsentManual()
  2. I'm doing this call await new GamesManagementApi(client).achievements.resetAllForAllPlayers(); and getting this in an exception: error=insufficient_scope, scope="https://www.googleapis.com/auth/games, which crashes my app.
  3. From then on, clientViaUserConsentManual() stops working in subsequent executions. I'm hitting on the assert that I'm questioning above, as refresh_token is not there in the response. Only by removing that assert I am able to test one more time.

So, why do we have that assert and do I have any other option but to remove it?

Unable to access Google Healthcare API

I've been creating a number of Dart/Flutter packages for dealing with healthcare data in the FHIR format (repos are here: https://github.com/fhir-fli). But I haven't been able to authenticate and authorize my app using this package. Should that functionality be available? (I just wanted to make sure it was something I was doing wrong, and not something that just hadn't been built out yet).

Refactor Platform.environment call in MetadataServerAuthorizationFlow for Node.js usage

One meaningful use-case platform is Node.js (eg. calling google arbitrary Google APIs using Firebase Functions interop library). It would be nice to be able to call clientFromMetadataServer in these Cloud Functions, which seems precluded only by the following line in MetadataServerAuthorizationFlow:

final metadataHost = Platform.environment[_GCE_METADATA_HOST_ENV_VAR] ??
        _DEFAULT_METADATA_HOST;

Is it possible to protect the Platform.environment call so that this function doesn't error on Node?

Can't get authorized client with flow on flutter web

Error: Failed to get user consent: idpiframe_initialization_failed.


    at Object.createErrorWithStack (http://localhost:56990/dart_sdk.js:4368:12)
    at Object._rethrow (http://localhost:56990/dart_sdk.js:38289:16)
    at async._AsyncCallbackEntry.new.callback (http://localhost:56990/dart_sdk.js:38283:13)
    at Object._microtaskLoop (http://localhost:56990/dart_sdk.js:38115:13)
    at _startMicrotaskLoop (http://localhost:56990/dart_sdk.js:38121:13)
    at http://localhost:56990/dart_sdk.js:33618:9

Browser shows the window to login but throw the error above simultaneously, and don't wait the response from user.

import "package:googleapis_auth/auth_browser.dart";

var id = new auth.ClientId('APP_ID.apps.googleusercontent.com', null);
var scopes = [drive.DriveApi.DriveFileScope, drive.DriveApi.DriveScope];

createImplicitBrowserFlow(id, scopes).then((BrowserOAuth2Flow flow) {
  flow.clientViaUserConsent().then((AuthClient client) {

    print(client); // never execute this
    client.close();
    flow.close();
  });
});

allow clientViaUserConsent to specify which account to use

I'm not sure I got everything right but in my browser application I use the following code on start:

flow.clientViaUserConsent(immediate: true)

and it seems to always load the first user that was logged in the browser "session". I created a simple webapp here:
https://github.com/alextekartik/dart-test/tree/master/googleapi_auths_test
that can be tested here:
http://gstest.tekartik.com/googleapis_auth_test

even if I switch to a different user (using flow.runHybridFlow(force: true)), the last authenticated user is not the one silently authenticated when the page reload which makes it impossible to always use the same account if the first one used was not the correct account the user wants to use.

I would to have a way to specify the "credentials" to try during flow.clientViaUserConsent(immediate: true), as I'm able to capture and save the last credentials used.
Otherwise is there a way to "save" the next automatically authenticated user in the same window

Or maybe I'm missing something and in that case I could ask in stack overflow but that is a question rather specific to this package.

ClientException "failed to parse header value"

Hi,

first of all thanks for your work on this package!

I'm trying to develop a flutter (web) application which needs to invoke access restricted Cloud Functions.

Therefore I have created a service account in my google cloud console and followed your example on how to retrieve an authenticated http client as an autonomous application.

final accountCredentials = new ServiceAccountCredentials.fromJson(r'''{ "private_key_id": "****", "private_key": "****", "client_email": "****.iam.gserviceaccount.com", "client_id": "****", "type": "service_account" }'''); var scopes = [CloudfunctionsApi.CloudPlatformScope]; AuthClient client = await clientViaServiceAccount(accountCredentials, scopes);

This seems to work fine. But when I try to use the received client to make a post request to my cloud function, I get a ClientException ("failed to parse header value").

http.Response resp = await client.post( CloudFunctiontriggerURL, body: {'data': userId});

As I understand the examples, this should work fine without specifying any headers manually in the POST function call. Correct?
However, even if I specify the header manually, I get this error.

Any help with this would be highly appreciated.

Consider moving auth.dart into src dir?

Will it be common or necessary for users to import googleapis_auth/auth.dart?

If not, we should put it in the src dir so folks are less likely to import the wrong library.

Failed assertion when doing clientViaUserConsent

From @floitsch on December 2, 2017 16:23

When doing a clientViaUserConsent I get the following assertion error:

When running without assertions, the code seems to work.

Unhandled exception:
'package:googleapis_auth/src/auth_http_utils.dart': Failed assertion: line 81 pos 12: 'credentials.refreshToken != null': is not true.
#0      _AssertionError._doThrowNew (dart:core-patch/dart:core/errors_patch.dart:37)
#1      _AssertionError._throwNew (dart:core-patch/dart:core/errors_patch.dart:33)
#2      new AutoRefreshingClient (package:googleapis_auth/src/auth_http_utils.dart:81:12)
#3      clientViaUserConsent.<anonymous closure> (package:googleapis_auth/auth_io.dart:53:32)
#4      _RootZone.runUnary (dart:async/zone.dart:1381)
#5      _FutureListener.handleValue (dart:async/future_impl.dart:129)
#6      _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:633)
#7      _Future._propagateToListeners (dart:async/future_impl.dart:662)
#8      _Future._complete (dart:async/future_impl.dart:467)
#9      _SyncCompleter.complete (dart:async/future_impl.dart:51)
#10     _completeOnAsyncReturn (dart:async-patch/dart:async/async_patch.dart:255)
#11     AuthorizationCodeGrantServerFlow.run (package:googleapis_auth/src/oauth2_flows/auth_code.dart:223:9)
#12     _RootZone.runUnary (dart:async/zone.dart:1381)
#13     _FutureListener.handleValue (dart:async/future_impl.dart:129)
#14     _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:633)
#15     _Future._propagateToListeners (dart:async/future_impl.dart:662)
#16     _Future._addListener.<anonymous closure> (dart:async/future_impl.dart:342)
#17     _microtaskLoop (dart:async/schedule_microtask.dart:41)
#18     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50)
#19     _Timer._runTimers (dart:isolate-patch/dart:isolate/timer_impl.dart:376)
#20     _Timer._handleMessage (dart:isolate-patch/dart:isolate/timer_impl.dart:401)
#21     _RawReceivePortImpl._handleMessage (dart:isolate-patch/dart:isolate/isolate_patch.dart:163)
main() {
  clientViaUserConsent(new ClientId(_CLIENT_ID, _CLIENT_SECRET), _SCOPES, (String str) {
    print("asking for consent: $str");
  }).then((client) {
  });

Copied from original issue: google/googleapis.dart#26

Got an error when using clientViaUserConsent client after some time

the client i got with clientViaUserConsent give me this error after some time of use :

Unhandled exception:
HttpException: Unexpected response (unsolicited response without request).
#0      new _HttpClientConnection.<anonymous closure> (dart:_http/http_impl.dart:1812:9)
#1      _RootZone.runUnaryGuarded (dart:async/zone.dart:1384:10)
#2      _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:357:11)
#3      _BufferingStreamSubscription._add (dart:async/stream_impl.dart:285:7)
#4      _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:808:19)
#5      _StreamController._add (dart:async/stream_controller.dart:682:7)
#6      _StreamController.add (dart:async/stream_controller.dart:624:5)
#7      _HttpParser._headersEnd (dart:_http/http_parser.dart:408:17)
#8      _HttpParser._doParse (dart:_http/http_parser.dart:740:15)
#9      _HttpParser._parse (dart:_http/http_parser.dart:324:7)
#10     _RootZone.runUnaryGuarded (dart:async/zone.dart:1384:10)
#11     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:357:11)
#12     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:285:7)
#13     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:808:19)
#14     _StreamController._add (dart:async/stream_controller.dart:682:7)
#15     _StreamController.add (dart:async/stream_controller.dart:624:5)
#16     _Socket._onData (dart:io-patch/socket_patch.dart:2044:41)
#17     _RootZone.runUnaryGuarded (dart:async/zone.dart:1384:10)
#18     _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:357:11)
#19     _BufferingStreamSubscription._add (dart:async/stream_impl.dart:285:7)
#20     _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:808:19)
#21     _StreamController._add (dart:async/stream_controller.dart:682:7)
#22     _StreamController.add (dart:async/stream_controller.dart:624:5)
#23     _RawSecureSocket._sendReadEvent (dart:io/secure_socket.dart:1002:19)
#24     Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
#25     _Timer._runTimers (dart:isolate-patch/timer_impl.dart:397:19)
#26     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

Hybrid Flow (again)

There's a (rather common) use-case where you will need the hybrid flow without approvalPrompt: force (and also with immediate: true): Server-side applications that don't need (or already have) offline access, but want to verify/authenticate the user that is making the call.

The user would log-in (without any additional popup if they have logged in in the past), the auth-flow will return a code (even if there is no offline access requested). This code is sent to the server and exchanged for an access token (not necessarily a refresh token) which can be used to determine who made the call and then allow (e.g. session-based) access to certain data/functionalities.
In this case you would use a simple AuthClient on the server-side since you might not have a refresh token.
If you had stored credentials before you could retrieve them based on who authenticated and create a AutoRefreshingAuthClient

In retrospect the easiest/most versatile solution would probably be to include the code as part of AccessCredentials and have all the necessary options on obtainAccessCredentialsViaUserConsent and clientViaUserConsent: {immediate: false, force: false, offline: false}

I understand the desire to keep the methods simple, but having extensively worked with Google auth in other languages I find the approach to call different methods for different use-cases rather confusing as opposed to calling one method (like gapi.auth.authorize) with different parameters.

Get new access token using refresh Token

I searched a lot about how to use refreshToken to get new access token but i could't find anything.
Here is the code i use to get user's credentials:

var authClient = await clientViaUserConsent(
    ClientId(_clientId, _clientSecret), 
    _scopes,
    (url) { launch(url);}
);
//Save Credentials
await storage.saveCredentials(authClient.credentials.accessToken,
    authClient.credentials.refreshToken);
return authClient;

After i get the user's credentials, i save them locally so i can use them later,

return authenticatedClient(
        http.Client(),
        AccessCredentials(
            AccessToken(credentials["type"], credentials["data"],
                DateTime.tryParse(credentials["expiry"])),
            credentials["refreshToken"],
            _scopes)
);

I don't know if there is a way to make use of the refreshToken to get new access token (which expires in one hour), it's a bad user experience to ask the user to grant you the access every single hour

Migrate to null safety

There are plenty of libraries that depend on this package, so it would be great if this could be migrated to null safety soon.

Throw a better error when a serviceAccount ClientId is used with obtainAccessCredentialsViaUserConsentManual

The URL encoding fails with a an unhelpful error because the ClientId has a null secret.

The null object does not have a getter 'length'.

NoSuchMethodError: method not found: 'length'
Receiver: null
Arguments: []
dart:core                                                       Uri.encodeQueryComponent
package:googleapis_auth/src/oauth2_flows/auth_code.dart 54:28   obtainAccessCredentialsUsingCode
package:googleapis_auth/src/oauth2_flows/auth_code.dart 123:12  AuthorizationCodeGrantAbstractFlow._obtainAccessCredentialsUsingCode
package:googleapis_auth/src/oauth2_flows/auth_code.dart 260:14  AuthorizationCodeGrantManualFlow.run.<fn>

get Token

by below code I can not get token. it is null. why ?
what should be scopes? I think my issue is for scopes.

createImplicitBrowserFlow(id, scopes).then((BrowserOAuth2Flow flow){
flow.obtainAccessCredentialsViaUserConsent().then((AccessCredentials credentials){
print(credentials.idToken);
// print(credentials.accessToken.data);
flow.close();
});
});

signOut()

Hi,

I've successfully logged with Google, but it seems (I may be mistaken) there is no way to signout (without Firebase).

clientViaApiKey - no such function

Hi!

I'am trying to use public youtube api. And create client via clientViaApiKey. But such function don't exists:

import "package:googleapis_auth/auth_io.dart";

void main() {

  var client = clientViaApiKey("key");

}

Documentation in readme.

Tell me please, how I can use public youtube api?

Couldn't sign you in

Hey i m using this library on flutter web and getting the below issue on browser
Screenshot 2020-04-29 at 4 36 18 PM

Docs unclear

I'm following the Installed/Console Application or obtain an authenticated HTTP client via flow.

You show the following code snippet:

import "package:googleapis_auth/auth_io.dart";

...

var id = new ClientId("....apps.googleusercontent.com", "...");
var scopes = [...];

clientViaUserConsent(id, scopes, prompt).then((AuthClient client) {
  // Authenticated and auto refreshing client is available in [client].
  // ...
  client.close();
});

void prompt(String url) {
  print("Please go to the following URL and grant access:");
  print("  => $url");
  print("");
}

That part works now, my console shows an url to open and I get a consent screen. The docs don't show what to do after though. What do I do after hitting the consent button? My browser is redirected to localhost which shows an error because it couldn't find that url.

According to the docs the redirect uri is generated automatically:

The redirect URIs for the automatic and manual flow will be configured automatically.

I honestly don't get the docs. I have no clue what I'm doing.

Using googleapis_auth to validate client tokens?

I'm using google_sign_in.dart package to authenticate my flutter client app with google. After authentication I receive an idToken and an accessToken. How can I use googleapis_auth library to validate these tokens server side?

I am NOT using any google service API! I would like only to perform token validation process.

Can't import googleapis to flutter for web

I added the below lines to my pubspec.yaml and imported the package.
googleapis: 0.54.0
googleapis_auth: 0.2.10

[WARNING]build_web_compilers:ddc_modules on lib/.ddc.meta_module.raw: Unable to read module information for package:googleapis_auth, make sure you have a dependency on it in your pubspec.
[SEVERE]build_web_compilers:entrypoint on web/main.dart: Unable to find modules for some sources, this is usually the result of either a
bad import, a missing dependency in a package (or possibly a dev_dependency
needs to move to a real dependency), or a build failure (if importing a
generated file).

Please check the following imports:

import "package:googleapis_auth/auth_io.dart"; from smartmirror_dueye|lib/setup/Login.dart at 5:1

[INFO] Running build completed, took 228ms
[INFO] Caching finalized dependency graph completed, took 145ms
[SEVERE] Failed after 377ms
[INFO] -------------------------------------------------------------------------------------------------------------------------------------------------

Browser popup warnings

This produces a browser popup warning:

querySelector('#signInButton').onClick.listen((_) {
  createImplicitBrowserFlow(clientId, scopes).then((BrowserOAuth2Flow flow) {
    flow.clientViaUserConsent().then(handleAuth).catchError((_) => handleAuth(null));
  });
});

This doesn't:

createImplicitBrowserFlow(clientId, scopes).then((BrowserOAuth2Flow flow) {
  querySelector('#signInButton').onClick.listen((_) {
    flow.clientViaUserConsent().then(handleAuth).catchError((_) => handleAuth(null));
  });
});

Might be worth to add a warning to the doc about this.
Also not sure how to properly handle/use flow.close() in this context.

Support for hybrid server-side flow (one-time codes)

It would be nice if support for hybrid flows could be added. When a client authenticates with Google, it receives both an access token and a code which the client then sends to the client's server, who then exchanges that code directly with Google's servers to get its own access token. More secure than sharing the access token as you need the client secret to exchange the code server-side.

It seems like you can set response_type='token code' when calling gapi.auth.authorize to achieve this but I haven't found it explicitly documented.

Flow:

Using the Google+ signin button for the hybrid flow:
https://developers.google.com/+/web/signin/server-side-flow

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.