反应原生的Google服务帐户身份验证

时间:2017-01-31 02:36:57

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

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

我很失落如何去做,因为我看到的所有前端代码都与传统的oauth2登录有关。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

我终于放弃了服务帐户的想法并使用了客户端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工作表API的REST请求。

这是一个处理auth然后从工作表中检索一些数据的组件的简单示例:

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

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

答案 1 :(得分:1)

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

您也可以使用以下链接,可以提供更多技术 Google Sheets API v4