android - 当我们调用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");
});
}
}
我已经做好了。
- 将脚本项目部署为 API 可执行文件。
- 为执行提供适当范围的 OAuth 令牌。
- 确保脚本和调用应用程序共享一个公共云平台 (GCP) 项目。
- 启用 Google Apps 脚本 API
我得到响应:-状态:403,消息:调用者没有权限
请指导我为什么会收到此错误。
解决方案
大家好,我得到了解决方案。
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,
)),
],
),
),
);
}
}
推荐阅读
- asp.net - 除非您清除浏览器缓存然后重新加载页面,否则不会调用登录 API 端点
- terraform - 具有 1Password 提供程序的 Terraform 计划失败,并出现 rpc 错误不可用的 desc 传输正在关闭
- python - Python中是否有任何直接函数可以从对象向量中获取某个属性的向量?
- snakemake - Snakemake 中文件更改时自动运行规则
- makefile - 使用 Makefile 中的 sed
- osgearth - osgearth 显示一些信息“ObjectWrapperManager::addWrapper()”
- flutter - 多个有状态类中的有状态小部件菜单
- git - 如何删除 github 上的 previos 提交文件或隐藏它?不小心泄露了私钥
- node.js - 与 Sequelize 通过关系多对多相关的计数问题
- windows - 从本地磁盘加载多个图像时,Flutter Windows 应用程序崩溃且没有错误