最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

oauth 2.0 - Google OAuth2: "invalid_grant" - Malformed auth code in FastAPI backend - Stack Overflow

programmeradmin2浏览0评论

I'm a beginner implementing Google OAuth2 login in a React frontend with FastAPI as my backend. However, I'm receiving the following error when exchanging the authorization code for tokens:

Token data received from Google: {'error': 'invalid_grant', 'error_description': 'Malformed auth code.'}

My backend handles the authorization code exchange as follows:

from fastapi import FastAPI, HTTPException
import requests as req
import os
import jwt
from urllib.parse import unquote
from google.auth.transport import requests
from google.oauth2 import id_token

app = FastAPI()

@app.post("/auth/google")
async def google_auth(data: TokenData):
    try:
        unquoted_token = unquote(data.token)  # Decode the token if needed
        print("Received Authorization Code (Backend):", unquoted_token)  # Debugging

        token_request_payload = {
            "client_id": GOOGLE_CLIENT_ID,
            "client_secret": os.getenv("GOOGLE_CLIENT_SECRET"),
            "code": unquoted_token,
            "grant_type": "authorization_code",
            "redirect_uri": "http://127.0.0.1:5173",  # Matches frontend setup
        }

        response = req.post(";, data=token_request_payload)
        token_data = response.json()
        logger.info("Token data received from Google: %s", token_data)

        if "id_token" in token_data:
            user_info = id_token.verify_oauth2_token(token_data["id_token"], requests.Request(), GOOGLE_CLIENT_ID)
            email = user_info["email"]
        else:
            raise HTTPException(status_code=400, detail="No ID token received from Google")

        return {"message": "User authenticated", "token": session_token, "user": user_info}

    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")

Frontend

import { GoogleLogin } from "@react-oauth/google";

const Login = () => {
  const handleLoginSuccess = async (response: any) => {
    const credential = response.credential;
    console.log("Raw authorization code", credential);

    try {
      const res = await fetch("http://127.0.0.1:8000/auth/google", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ token: credential.trim() }),
      });

      const data = await res.json();
      console.log("Backend Response:", data);
    } catch (error) {
      console.error("Error sending token to backend:", error);
    }
  };

  return (
    <GoogleLogin
      onSuccess={handleLoginSuccess}
      onError={() => console.log("Login Failed")}
      useOneTap
      access_type="offline"
      prompt="consent"
      response_type="code" // Requesting an authorization code
      scope="openid email profile"
    />
  );
};

export default Login;

Debugging Steps Taken

Confirmed the authorization code is received: The frontend prints a long authorization code, and the backend logs show it is being received.

Checked the redirect URI: It matches in both frontend setup and backend request (http://127.0.0.1:5173).

Verified the client ID and secret: They are correctly set in the backend.

Used unquote to decode the token: No change, still getting invalid_grant error.

Tried response_type="code" in @react-oauth/google: Still receiving the error.

Questions:

  1. Why is Google returning invalid_grant with Malformed auth code.?
  2. Is @react-oauth/google providing an ID token instead of an authorization code despite setting response_type="code"?
  3. How can I correctly exchange the code for an access token in FastAPI? Any guidance would be appreciated!
发布评论

评论列表(0)

  1. 暂无评论