You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask路由含#号致404错误,如何获取Google API返回的id_token?

Fixing 404 & Retrieving Google id_token in Flask with Fragment URLs

Hey there! Let's tackle this problem step by step—your 404 error and missing id_token are tied together, and it all comes down to how browsers handle URL fragments (the # part).

Why You're Seeing a 404

The #id_token=... portion of your URL is called a fragment identifier. Browsers never send this part of the URL to the server—so when Google redirects you to http://localhost:8000/afterlogin/#id_token=..., your Flask server only receives the request for /afterlogin/. If you haven't defined a route for that path, Flask throws a 404. Even if you did have the route, the server still can't access the id_token from the fragment.

Solution 1: Get the id_token via Frontend JavaScript (For Implicit Flow)

Since the fragment lives only in the browser, you'll need to use JavaScript to grab it, then send it to your Flask backend. Here's how to set this up:

Step 1: Add the Flask Route for /afterlogin/

First, create a route that returns an HTML page with JavaScript to handle the fragment:

from flask import Flask, render_template, request, jsonify

app = Flask(__name__)

# Route to serve the page that will process the fragment
@app.route('/afterlogin/')
def after_login():
    return render_template('after_login.html')

# Route to receive the id_token from the frontend
@app.route('/api/save-token', methods=['POST'])
def save_token():
    id_token = request.json.get('id_token')
    if not id_token:
        return jsonify({'error': 'No token provided'}), 400
    
    # Here you can validate the id_token with Google, save it to a session, etc.
    # Example validation (using google-auth-library):
    # from google.oauth2 import id_token
    # from google.auth.transport import requests
    # try:
    #     id_info = id_token.verify_oauth2_token(id_token, requests.Request(), YOUR_CLIENT_ID)
    #     user_id = id_info['sub']
    # except ValueError:
    #     return jsonify({'error': 'Invalid token'}), 400
    
    return jsonify({'status': 'success', 'message': 'Token received'})

if __name__ == '__main__':
    app.run(port=8000, debug=True)

Step 2: Create the HTML Template with JavaScript

Make a templates/after_login.html file that reads the fragment and sends it to your backend:

<!DOCTYPE html>
<html>
<head>
    <title>Processing Login...</title>
</head>
<body>
    <script>
        // Extract the fragment (remove the leading #)
        const fragment = window.location.hash.slice(1);
        // Parse the fragment like query parameters
        const params = new URLSearchParams(fragment);
        const idToken = params.get('id_token');

        if (idToken) {
            // Send the token to Flask backend
            fetch('/api/save-token', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({id_token: idToken}),
            })
            .then(response => response.json())
            .then(data => {
                console.log('Success:', data);
                // Redirect to another page or show a success message here
                window.location.href = '/dashboard';
            })
            .catch(error => {
                console.error('Error:', error);
                alert('Failed to process login. Please try again.');
            });
        } else {
            alert('No login token found. Please try logging in again.');
        }
    </script>
</body>
</html>

Solution 2: Use Authorization Code Flow (More Secure)

If your app is a server-side application (most Flask apps are), you should switch to Google's Authorization Code Flow instead of Implicit Flow. This flow returns an authorization code as a query parameter (not a fragment), which your Flask server can directly access. You then exchange this code for the id_token and access_token securely on the backend.

Here's a quick snippet of how this works:

import requests
from flask import Flask, request, jsonify

app = Flask(__name__)
YOUR_CLIENT_ID = 'your-google-client-id'
YOUR_CLIENT_SECRET = 'your-google-client-secret'
REDIRECT_URI = 'http://localhost:8000/afterlogin/'

@app.route('/afterlogin/')
def after_login():
    code = request.args.get('code')
    if not code:
        return jsonify({'error': 'Authorization code missing'}), 400
    
    # Exchange code for tokens
    token_response = requests.post(
        'https://oauth2.googleapis.com/token',
        data={
            'code': code,
            'client_id': YOUR_CLIENT_ID,
            'client_secret': YOUR_CLIENT_SECRET,
            'redirect_uri': REDIRECT_URI,
            'grant_type': 'authorization_code'
        }
    )
    token_data = token_response.json()
    id_token = token_data.get('id_token')
    
    # Validate and use the id_token here
    return jsonify({'id_token': id_token})

if __name__ == '__main__':
    app.run(port=8000, debug=True)

Don't forget to update your Google OAuth 2.0 client settings to use the Authorization Code Flow (select "Web application" type and ensure your redirect URI is correct).

Final Notes

  • The 404 error is fixed by adding the /afterlogin/ route in Flask.
  • Fragments are client-side only, so you need JS to access them if using Implicit Flow.
  • Authorization Code Flow is more secure because tokens are never exposed in the browser's URL or history.

内容的提问来源于stack exchange,提问作者VivekChoudhary1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:34:07