Google OAuth Refresh Token始终为Undefined问题求助(附代码)
Google OAuth refreshToken 返回 undefined 问题求助
我知道这个问题被提过很多次,但试过所有可行方案后,我的refreshToken仍然返回undefined。已经执行了以下操作:
- 删除应用在第三方访问权限中的记录;
- 删除MongoDB中对应的用户条目;
- 在Passport配置中设置
accessType: 'offline'; - 尝试添加
prompt: 'consent'和approvalPrompt: 'force'参数; - 用
passport.authorize替换passport.authenticate; - 移除离线访问配置后,在回调URL后拼接
?access_type=offline。
补充说明:应用目前在Google开发者控制台处于测试状态,尚未发布。OAuth授权环节没有出现offline_access的授权选项。
我正在开发一个MERN栈应用,允许用户关联谷歌账号并调度YouTube直播视频,当前专注于Node.js后端开发。相关代码如下:
oauth/passportConfig.js
require('dotenv').config(); const passport = require("passport"); const axios = require("axios"); const GoogleStrategy = require("passport-google-oauth20").Strategy; const GoogleUser = require("../models/usergoogleModel"); // Initialize Passport.js passport.initialize(); // Configure Passport.js with Google OAuth 2.0 Strategy passport.use( new GoogleStrategy( { clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, callbackURL: process.env.GOOGLE_CALLBACK_URL, scope: [ "https://www.googleapis.com/auth/youtube", "https://www.googleapis.com/auth/youtube.force-ssl", "https://www.googleapis.com/auth/youtube.upload", ], skipUserProfile: true, accessType: 'offline' }, async (accessToken, refreshToken, _profile, done) => { try { console.log("Refresh Token:", refreshToken); // Make a request to the YouTube API to get the user's profile information const response = await axios.get( "https://www.googleapis.com/youtube/v3/channels", { params: { part: "snippet,contentDetails,statistics", mine: "true", }, headers: { Authorization: `Bearer ${accessToken}`, }, } ); const youtubeProfile = response.data.items[0]; const googleId = youtubeProfile.id; // Find or create the user based on googleId let user = await GoogleUser.findOne({ googleId }); if (!user) { user = new GoogleUser({ googleId, accessToken, refreshToken, }); } else { // Update user's access token and refresh token user.accessToken = accessToken; user.refreshToken = refreshToken; } await user.save(); done(null, user); } catch (err) { console.error( "Error in OAuth callback:", err.response ? err.response.data : err.message ); done(err); } } ) ); // Implement Passport.js Serialization and Deserialization passport.serializeUser((user, done) => { done(null, user); }); passport.deserializeUser(async (id, done) => { try { const user = await GoogleUser.findById(id); if (!user) { // If user is not found, pass null as the user return done(null, null); } done(null, user); } catch (err) { done(err); } }); module.exports = passport;
controllers/authgoogleController.js
const passport = require("passport"); // Controller function to initiate Google OAuth authentication exports.googleAuth = passport.authenticate("google", { }); // Callback function for Google OAuth authentication exports.googleAuthCallback = (req, res, next) => { passport.authenticate("google", (err, user, info) => { if (err) { return next(err); } if (!user) { // Handle authentication failure // return res.redirect("/login"); // Redirect to the login page or handle appropriately return res.send("Login failed."); } // Handle authentication success res.send("Google OAuth authentication successful!"); // Send a response indicating successful authentication })(req, res, next); }; // Controller function for user logout exports.logout = (req, res) => { req.logout(() => { // res.redirect("/"); // Redirect to the home page after logout res.send("Logout successful!"); }); };
routes/authgoogle.js
const express = require("express"); const router = express.Router(); const authgoogleController = require("../controllers/authgoogleController"); // Route for initiating Google OAuth authentication router.get("/", authgoogleController.googleAuth); // Route for handling the OAuth callback router.get("/callback", authgoogleController.googleAuthCallback); // Route for user logout router.get("/logout", authgoogleController.logout); module.exports = router;
models/usergoogleModel.js
const mongoose = require("mongoose"); const usergoogleSchema = new mongoose.Schema({ googleId: String, accessToken: String, refreshToken: String, }); module.exports = mongoose.model("GoogleUser", usergoogleSchema);
server.js
require("dotenv").config(); const express = require("express"); const session = require("express-session"); const mongoose = require("mongoose"); const passport = require("./oauth/passportConfig") const authgoogleRoutes = require("./routes/authgoogle"); // Express app const app = express(); // Middleware to initialize Passport and configure session app.use( session({ secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: true, }) ); app.use(passport.session()); // Routes app.use("/auth/google", authgoogleRoutes); // Connect to db mongoose .connect(process.env.MONGO_URI) .then(() => { // Listen for requests app.listen(process.env.PORT, () => { console.log("Connected to the db & listening on port", process.env.PORT); }); }) .catch((error) => { console.log(error); });
内容的提问来源于stack exchange,提问作者threehappypenguins
相关产品推荐
相关产品推荐

