【问题标题】:Google service account authentication from react native来自 React Native 的 Google 服务帐户身份验证
【发布时间】:2017-06-16 08:57:36
【问题描述】:

我想在我的 react 本机应用程序中使用服务帐户身份验证,以便让人们无需登录他们的 Google 帐户即可更新电子表格。

我不知道该怎么做,因为我看到的所有前端代码都与传统的 oauth2 登录有关。

有什么想法吗?

【问题讨论】:

    标签: android react-native google-api google-authentication


    【解决方案1】:

    我终于放弃了服务帐户的想法,使用了客户端 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 sheet 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;
    

    如果有更好的方法,请告诉我。

    【讨论】:

    • 非常感谢您跟进您的发现。我一直在尝试自己解决同样的问题,并且得出了同样的结论,即这是不可能的。
    【解决方案2】:

    我对此并不完全了解,但是可以,如果您可以将工作表权限设置为公开并从您的应用程序访问,它将不会要求您进行身份验证。

    您也可以使用下面的链接可能有助于更多技术 Google Sheets API v4

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-16
      • 2017-09-14
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 2019-04-14
      • 2017-03-01
      • 2020-05-21
      相关资源
      最近更新 更多