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

如何实现Next.js前端到Node.js后端的Google用户认证

独立Node.js后端(Passport.js)+ Next.js前端 Google 认证实现方案

核心思路

不能直接在Next.js前端调用Google认证的回调URL,因为回调URL是后端Passport.js用来接收Google返回的授权码、完成用户信息校验与存储的专属接口。前端的核心作用是引导用户跳转到后端的Google认证发起接口,后续流程由后端与Google交互完成,最后再回调到前端并处理登录状态。

具体实现步骤

1. 后端配置确认

确保你的Node.js后端已配置好Passport.js的Google策略,且存在两个关键接口:

  • 发起认证接口(如/auth/google):用于重定向用户到Google授权页面
  • 回调处理接口(如/auth/google/callback):接收Google返回的授权码,完成用户信息验证、存入MySQL,最后生成会话或JWT并跳转到前端指定页面

示例后端Express路由:

// 发起Google认证
app.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }));

// 回调处理逻辑
app.get('/auth/google/callback', 
  passport.authenticate('google', { failureRedirect: 'http://localhost:3000/login' }),
  (req, res) => {
    // 生成JWT(若用会话则无需此步骤,直接依赖express-session)
    const token = jwt.sign({ userId: req.user.id }, 'your-secret-key');
    // 跳转到前端登录成功页并携带token
    res.redirect(`http://localhost:3000/login-success?token=${token}`);
  }
);

2. Next.js前端登录页实现

在Next.js中创建登录页面(如pages/login.js),添加Google登录按钮,点击后直接跳转到后端的认证发起接口:

export default function LoginPage() {
  const handleGoogleLogin = () => {
    window.location.href = 'http://localhost:3001/auth/google';
  };

  return (
    <div className="login-container">
      <h1>账号登录</h1>
      <button onClick={handleGoogleLogin} className="google-login-btn">
        用Google账号登录
      </button>
    </div>
  );
}

3. 前端处理登录回调

当后端完成Google认证后,会跳转到前端指定页面(如pages/login-success.js),这里需要获取后端传递的token,存储到本地并完成页面跳转:

import { useEffect } from 'react';
import { useRouter } from 'next/router';

export default function LoginSuccessPage() {
  const router = useRouter();

  useEffect(() => {
    const token = router.query.token;
    if (token) {
      // 将token存入localStorage,供后续接口请求使用
      localStorage.setItem('authToken', token);
      // 跳转到主页
      router.push('/');
    } else {
      // 无有效token,返回登录页
      router.push('/login');
    }
  }, [router]);

  return <div>登录成功,正在跳转...</div>;
}

4. 前端接口请求的身份校验

后续前端调用后端API时,需在请求头中携带token,示例用axios实现:

import axios from 'axios';

const api = axios.create({
  baseURL: 'http://localhost:3001/api',
});

// 请求拦截器,自动携带token
api.interceptors.request.use((config) => {
  const token = localStorage.getItem('authToken');
  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// 示例:调用需认证的用户信息接口
export const fetchUserProfile = async () => {
  const response = await api.get('/profile');
  return response.data;
};

5. 后端身份校验中间件

后端需添加中间件验证前端传递的token有效性,确保接口仅对已认证用户开放:

const jwt = require('jsonwebtoken');

const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];

  if (!token) return res.sendStatus(401);

  jwt.verify(token, 'your-secret-key', (err, user) => {
    if (err) return res.sendStatus(403);
    req.user = user;
    next();
  });
};

// 示例:需认证的用户信息接口
app.get('/api/profile', authenticateToken, (req, res) => {
  db.query('SELECT * FROM users WHERE id = ?', [req.user.userId], (err, results) => {
    if (err) throw err;
    res.json(results[0]);
  });
});

关键注意事项

  • 跨域配置:后端需使用cors中间件允许前端域名请求,示例:
    const cors = require('cors');
    app.use(cors({ origin: 'http://localhost:3000', credentials: true }));
    
  • Google开发者控制台:确保回调URL设置为后端的回调接口(如http://localhost:3001/auth/google/callback),并添加前端、后端地址到授权来源列表。
  • 会话与JWT选择:若用会话,需配置express-session结合MySQL存储会话;JWT更适合前后端分离场景,无需会话存储。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 14:43:11