我想在我的 react 原生应用程序中使用服务帐户身份验证,以便让人们更新电子表格而无需登录他们的 Google 帐户。
我对如何做到这一点感到非常迷茫,因为我看到的所有前端代码都与传统的 oauth2 登录有关。
知道吗?
我终于放弃了服务帐户的想法并使用了客户端 oauth。
我依赖于以下 React Native 库: https://github.com/joonhocho/react-native-google-sign-in
这是我的身份验证服务(简化,基于redux + redux thunk):
// <project_folder>/src/services/auth.js
import GoogleSignIn from 'react-native-google-sign-in';
import { store } from '../store';
import auth from '../actions/auth';
export default () => {
GoogleSignIn.configure({
// https://developers.google.com/identity/protocols/googlescopes
scopes: ['https://www.googleapis.com/auth/spreadsheets'],
clientID: 'XXXXXXXXXXXXXXXXX.apps.googleusercontent.com',
}).then(() => {
GoogleSignIn.signInPromise().then((user) => {
store.dispatch(auth(user.accessToken));
}).catch((err) => {
console.log(err);
});
}).catch((err) => {
console.log(err);
});
};
因此,我的 redux 商店中有了user.accessToken
,并且可以在其他地方使用它来创建对 google sheets API 的 REST 请求。
下面是一个处理身份验证然后从工作表中检索一些数据的组件的简单示例:
// <project_folder>/src/main.js
import React, { Component } from 'react';
import {
ActivityIndicator,
Text,
View,
StyleSheet,
} from 'react-native';
import { connect } from 'react-redux';
import auth from './services/auth';
import Sheet from './services/sheet';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
});
const sheetId = 'XX-XXXXXX_XXX_XXXXXXXXXXXXXXXXXXXXXX';
class Main extends Component {
constructor(props) {
super(props);
this.state = {
animating: true,
};
}
componentDidMount() {
auth();
}
componentWillUpdate(nextProps) {
if (this.props.token !== nextProps.token) this.setState({ animating: false });
}
componentDidUpdate(nextProps) {
this.sheet = new Sheet(id, this.props.token);
this.sheet.getDoc();
}
render() {
return (
<View style={styles.container}>
<ActivityIndicator
animating={this.state.animating}
style={{ height: 80 }}
size="large"
/>
{!this.state.animating &&
<Text>
{this.props.name}
</Text>
}
</View>
);
}
}
const mapStateToProps = (state) => {
return {
token: state.auth.get('token'),
name: state.sheet.get('name'),
};
};
export default connect(mapStateToProps)(Main);
这是读/写工作表的基本服务:
// <project_folder>/services/sheet.js
import { store } from '../store';
import {
nameGet,
valueGet,
valuePost,
}
from '../actions/sheet';
class Sheet {
constructor(id, token) {
this.id = id;
this.token = token;
this.endPoint = `https://sheets.googleapis.com/v4/spreadsheets/${this.id}`;
}
getDoc() {
fetch(`${this.endPoint}?access_token=${this.token}`).then((response) => {
response.json().then((data) => {
console.log(data);
store.dispatch(nameGet(data.properties.title));
});
});
}
getCell(sheet, cell) {
const range = `${sheet}!${cell}`;
fetch(`${this.endPoint}/values/${range}?access_token=${this.token}`)
.then((response) => {
response.json()
.then((data) => {
console.log(data);
store.dispatch(valueGet(data.values[0][0]));
})
.catch((err) => {
console.log(err);
});
})
.catch((err) => {
console.log(err);
});
}
writeCell(sheet, cell, value) {
const range = `${sheet}!${cell}`;
const body = JSON.stringify({ values: [[value]] });
fetch(
`${this.endPoint}/values/${range}?valueInputOption=USER_ENTERED&access_token=${this.token}`,
{
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body,
}
)
.then((response) => {
response.json()
.then((data) => {
console.log(data);
store.dispatch(valuePost('OK'));
})
.catch((err) => {
console.log(err);
});
})
.catch((err) => {
console.log(err);
});
}
}
export default Sheet;
如果有更好的方法,请告诉我。
我对此并不完全了解,但是是的,如果您可以将工作表权限设置为公共并从您的应用程序访问,它不会要求您进行身份验证。
您也可以使用以下链接可能有助于更多技术性的谷歌表格API v4