首页 > 解决方案 > 当我们调用apps-script api时得到“调用者没有权限[403]”

问题描述

大家好,我正在研究 google apps-script Api。

import 'package:flutter/material.dart';
import 'package:googleapis/script/v1.dart';
import 'package:googleapis_auth/auth_io.dart';

class ApiTest extends StatefulWidget {
  @override
  _ApiTestState createState() => _ApiTestState();
}

class _ApiTestState extends State<ApiTest> {
  var accountCredentials = new ServiceAccountCredentials.fromJson({
"type": "service_account",
"project_id": "xxxxxxxxx",
"private_key_id": "xxxxxxxxxxxxxxx",
"private_key":
    "-----BEGIN PRIVATE KEY-----\nMIIExxxxxxxxxxxxxxxxDJlUBIRuMwo=\n-----END PRIVATE KEY-----\n",
"client_email": "xxxxxxx@yyyyyy.iam.gserviceaccount.com",
"client_id": "0000000000000",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url":
    "https://www.googleapis.com/robot/v1/metadata/x509/xxxxxxx%40yyyyyy.iam.gserviceaccount.com"
  });
  List<String> scopes = [
"https://www.googleapis.com/auth/documents.currentonly",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/script.storage",
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/script.send_mail",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/sqlservice"
  ];

  @override
  void initState() {
    super.initState();
    main();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
  body: Container(
    color: Colors.white,
    child: Center(child: Text("Hello Worlds")),
  ),
);
  }

  void main() {
    clientViaServiceAccount(accountCredentials, scopes).then((http_client) {
      var service = new ScriptApi(http_client);
  ExecutionRequest request = new ExecutionRequest();
  request.function = "projectSummary";
  service.scripts.run(
      request, "1C9zxs82nICdyH_O8BMIU9vLpFLmDIZmzw5-3HVnJRvusrr8zMa8nIKXV");
});
  }
}

我已经做好了。

  1. 将脚本项目部署为 API 可执行文件。
  2. 为执行提供适当范围的 OAuth 令牌。
  3. 确保脚本和调用应用程序共享一个公共云平台 (GCP) 项目。
  4. 启用 Google Apps 脚本 API

项目中使用的范围 在此处输入图像描述

我得到响应:-状态:403,消息:调用者没有权限

请指导我为什么会收到此错误。

标签: androidflutterdartgoogle-api

解决方案


大家好,我得到了解决方案。

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:googleapis/drive/v3.dart' as ga;
import 'package:googleapis/script/v1.dart';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Google Drive',
      theme: ThemeData(
        primarySwatch: Colors.indigo,
      ),
      home: MyHomePage(title: 'Google Drive'),
    );
  }
}

class GoogleHttpClient extends IOClient {
  Map<String, String> _headers;

  GoogleHttpClient(this._headers) : super();

  @override
  Future<http.StreamedResponse> send(http.BaseRequest request) =>
      super.send(request..headers.addAll(_headers));

  @override
  Future<http.Response> head(Object url, {Map<String, String> headers}) =>
  super.head(url, headers: headers..addAll(_headers));
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final storage = new FlutterSecureStorage();
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final GoogleSignIn googleSignIn = GoogleSignIn(scopes: [
'https://www.googleapis.com/auth/drive.appdata',
"https://www.googleapis.com/auth/documents.currentonly",
"https://www.googleapis.com/auth/script.scriptapp",
"https://www.googleapis.com/auth/script.storage",
"https://www.googleapis.com/auth/drive.readonly",
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/script.send_mail",
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/sqlservice"
  ]);
  GoogleSignInAccount googleSignInAccount;
  ga.FileList list;
  var signedIn = false;

  Future<void> _loginWithGoogle() async {
    signedIn = await storage.read(key: "signedIn") == "true" ? true : false;
    googleSignIn.onCurrentUserChanged
        .listen((GoogleSignInAccount googleSignInAccount) async {
      if (googleSignInAccount != null) {
        _afterGoogleLogin(googleSignInAccount);
      }
    });
    if (signedIn) {
      try {
        googleSignIn.signInSilently().whenComplete(() => () {});
      } catch (e) {
        storage.write(key: "signedIn", value: "false").then((value) {
          setState(() {
            signedIn = false;
          });
        });
      }
    } else {
      final GoogleSignInAccount googleSignInAccount =
          await googleSignIn.signIn();
      _afterGoogleLogin(googleSignInAccount);
    }
  }

  Future<void> _afterGoogleLogin(GoogleSignInAccount gSA) async {
    googleSignInAccount = gSA;
    final GoogleSignInAuthentication googleSignInAuthentication =
        await googleSignInAccount.authentication;

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

    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);

print('signInWithGoogle succeeded: $user');

storage.write(key: "signedIn", value: "true").then((value) {
  setState(() {
    signedIn = true;
  });
});
}

void _logoutFromGoogle() async {
    googleSignIn.signOut().then((value) {
      print("User Sign Out");
      storage.write(key: "signedIn", value: "false").then((value) {
        setState(() {
          signedIn = false;
        });
      });
    });
  }
  Future<void> _callApi() async {
    var client = GoogleHttpClient(await googleSignInAccount.authHeaders);

    var service = new ScriptApi(client);
    ExecutionRequest request = new ExecutionRequest();
    request.function = "functionName";
   var scriptId="1C9zxs82nICdyH_O8BMIU9vLpFLmDIZmzw5-3HVnJRvusrr8zMa8nIKXV";
    try {
      service.scripts.run(request,scriptId).then((op) {
    op.response.forEach((key, value) {
      print("key: $key");
      print("value: $value");
    });
  });
} catch (err) {
  print('error err');
  print(err);
}
}

@override
Widget build(BuildContext context) {
  return Scaffold(
   appBar: AppBar(
     title: Text(widget.title),
   ),
   body: Center(
     child: Column(
       mainAxisAlignment: MainAxisAlignment.center,
       children: <Widget>[
         (signedIn
             ? FlatButton(
                 child: Text('Call Api'),
                 onPressed: _callApi,
                 color: Colors.green,
               )
             : Container()),
         (signedIn
             ? FlatButton(
                 child: Text('Google Logout'),
                 onPressed: _logoutFromGoogle,
                 color: Colors.green,
               )
             : FlatButton(
                 child: Text('Google Login'),
                 onPressed: _loginWithGoogle,
                 color: Colors.red,
              )),
      ],
    ),
  ),
);
}
}

推荐阅读