首页 > 解决方案 > 反应谷歌登录不适用于 axios

问题描述

我在前端使用 google 实现身份验证,它将访问令牌发送到后端,后端检查令牌,如果它有效,它将返回一个令牌,该令牌将允许访问受保护的资源。

在 medium 上遵循了本教程,我已经实现了所有内容并且效果很好。问题在于向后端发送请求的级别,获取一切正常,但如果我尝试实现 axios,服务器会发送响应 401 未授权

带取

const googleResponse = (response) => {
        const tokenBlob = new Blob([
            JSON.stringify({
                access_token: response.accessToken
            }, null, 2)
        ], {type : 'application/json'});
        const options = {
            method: 'POST',
            body: tokenBlob,

        };

        fetch('http://localhost:8000/api/auth/google/login', options).then(r => {
            const token = r.headers;
            r.json().then(user => {
                if (token) {
                    setData({
                        //...data, isAuthenticated: true, user: user, token: token
                        ...data, isAuthenticated: true, user: user, token: token
                    })
                }
            });
        })
    };

与 axios

    const responseGoogle = (response) => {
        const tokenBlob = new Blob([
            JSON.stringify({
                access_token: response.accessToken
            }, null, 2)
        ]);

        axios.post('http://localhost:8000/api/auth/google/login', tokenBlob)
            .then(response => {
                const token = response.headers;
                if (token){
                    setData({
                        ...data, token: token, isAuthenticated: true
                    })
                }
            })
    };

完整代码

import React, {useState} from "react";
import {config} from "./config";
import {GoogleLogin, GoogleLogout} from 'react-google-login';
import axios from 'axios';

const App = () => {
    const [data, setData] = useState({
        isAuthenticated : false,
        token : '',
        user : null
    })
    const {isAuthenticated, user} = data;


    const logout = () => {
        setData({
            ...data, token: "", user: null, isAuthenticated: false
        })
    };

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


    const googleResponse = (response) => {
        const tokenBlob = new Blob([
            JSON.stringify({
                access_token: response.accessToken
            }, null, 2)
        ], {type : 'application/json'});
        const options = {
            method: 'POST',
            body: tokenBlob,

        };

        fetch('http://localhost:8000/api/auth/google/login', options).then(r => {
            const token = r.headers;
            r.json().then(user => {
                if (token) {
                    setData({
                        //...data, isAuthenticated: true, user: user, token: token
                        ...data, isAuthenticated: true, user: user, token: token
                    })
                }
            });
        })
    };

    let content = !! isAuthenticated ?
        (
            <div>
                <p>Authenticated</p>
                <div>
                    {user && user.email}
                </div>
                <div>
                    <GoogleLogout clientId={config.GOOGLE_CLIENT_ID}
                                  buttonText="Logout"
                                  onLogoutSuccess={logout}
                    />
                </div>
            </div>
        ) :
        (
            <div>
                <GoogleLogin
                    clientId={config.GOOGLE_CLIENT_ID}
                    buttonText="Login"
                    onSuccess={googleResponse}
                    onFailure={onFailure}
                    isSignedIn
                />

            </div>
        );

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

export default App;

标签: javascriptreactjsaxiosfetch

解决方案


在 fetch 调用中,您包括{type : 'application/json'},但不包括 axios 调用的配置标头。

请尝试包括应用程序类型配置:

const responseGoogle = (response) => {

  let tokenBlob = new Blob([
    JSON.stringify({
        access_token: response.accessToken
    }, null, 2)
  ]);

  let config = {
    headers: {
      'Content-Type': 'application/json'
    }
  };

  // The call takes the URl, the body (your stringified blob), and the headers config
  axios.post('http://localhost:8000/api/auth/google/login', tokenBlob, config)
      .then(response => {
          const token = response.headers;
          if (token){
              setData({
                  ...data, token: token, isAuthenticated: true
              });
          }
      });
};

推荐阅读