4

I got question about implementing google login. I was able to implement Google Login button on my react app using an open source library called [react-google-login][1]. I was able to set up the backend server using python flask, and host the api on Heroku: http://arrangement-server.herokuapp.com/login. The client side should just be redirecting to google and then getting a token when it redirects back. But I have trouble to getting any token from Google login information on the frontend through react component.
I think there's an issue with my header for access token and request from [app.py][2]

google = oauth.remote_app('google',
                          base_url='https://www.google.com/accounts/',
                          authorize_url='https://accounts.google.com/o/oauth2/auth',
                          request_token_url=None,
                          request_token_params={'scope': 'https://www.googleapis.com/auth/userinfo.email',
                                                'response_type': 'code'},
                          access_token_url='https://accounts.google.com/o/oauth2/token',
                          access_token_method='POST',
                          access_token_params={'grant_type': 'authorization_code'},
                          consumer_key=GOOGLE_CLIENT_ID,
                          consumer_secret=GOOGLE_CLIENT_SECRET)


@app.route("/")
def home_page():
    access_token = session.get('access_token')
    if access_token is None:
        return redirect(url_for('login'))

    access_token = access_token[0]
    from urllib2 import Request, urlopen, URLError

    headers = {'Authorization': 'OAuth '+access_token}
    req = Request('https://www.googleapis.com/oauth2/v1/userinfo',
                  None, headers)
    try:
        res = urlopen(req)
    except URLError, e:
        if e.code == 401:
            # Unauthorized - bad token
            session.pop('access_token', None)
            return redirect(url_for('login'))
        return res.read()

    return res.read()

my react component at App.js

import React, { Component } from 'react'
import './App.css'
import router from 'config/router'
import { Provider } from 'react-redux'
import store from 'store/index'
import { GoogleLogin } from 'react-google-login'
import config from './config.json'

class App extends Component {

    constructor() {
        super();
        this.state = { isAuthenticated: false, user: null, token:
            ''};
    }
    logout = () => {
        this.setState({isAuthenticated: false, token: '', user: null})
    };

    onFailure = (error) => {
        alert(error);
    };

    googleResponse = (response) => {
        console.log(response);
        const tokenBlob = new Blob([JSON.stringify({access_token: response.accessToken}, null, 2)], {type : 'application/json'});
        const options = {
            method: 'POST',
            body: tokenBlob,
            mode: 'cors',
            cache: 'default'
        };
        fetch('http://arrangement-server.herokuapp.com/login', options).then(r => {
            const token = r.headers.get('x-auth-token');
            r.json().then(user => {
                if (token) {
                    this.setState({isAuthenticated: true, user, token})
                }
            });
        })
    };

    render() {
        let content = !!this.state.isAuthenticated ?
            (
                <div>
                    <p>Authenticated</p>
                    <div>
                        {this.state.user.email}
                    </div>
                    <div>
                        <button onClick={this.logout} className="button">
                            Log out
                        </button>
                    </div>
                </div>
            ) :
            (
                <div>
                    <GoogleLogin
                        clientId={config.GOOGLE_CLIENT_ID}
                        buttonText="Login"
                        onSuccess={this.googleResponse}
                        onFailure={this.onFailure}
                    />
                </div>
            );

        return (
            <div className="App">
                {content}
            </div>
        );
    }
}



export default App

Code above can be found at my project

3 Answers 3

3

/login route verb should be POST

Sign up to request clarification or add additional context in comments.

1 Comment

where ? can you name it? is it on frontend or backend , which line? which part of code?
3

I have looked your code. I am able to run that with your google client Id. So, at the frontend token and profile details are getting with "react-google-login". The problem is at the /login api. This api should be "POST". You can check my attached screenshot.

enter image description here

I saw you have created config.json for id and secrets but forgot to drop the commit which had the client Id. Shouldn't commit the configId's in code :P

Comments

3

So, The Frontend using the react library react-google-login gets the access token from google server. So the backend side doesn't need to get the access token. The front end side needs to give the access token to the backend side via post request.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.