如何在同一个应用程序中两次使用 passport-google-oauth20
how to use passport-google-oauth20 twice in the same app
我试图在我的节点应用程序中使用 passport-google-oauth20 两次,但它不起作用。还在学习护照认证。
问题来了:
我制作了一个用户使用 google(/auth.google) 登录的按钮和一个用户使用 google(/users/google) 注册的按钮。我想要它,以便如果用户已经使用 google 在我的应用程序上注册并且他继续按下“使用 google 注册”按钮,他应该被重定向回注册页面(身份验证失败) .在我的例子中,当我添加一次策略并仅添加一个登录按钮(不注册)时,身份验证有效并且用户被重定向到仪表板。但是,当我在 passport.js 中再次添加策略并且“已注册用户”尝试使用 google 登录时,他被重定向到注册页面(找到使用 google 按钮注册的页面) 而不是仪表板。我知道没有必要做这样的事情,也不需要再次使用相同的 strat 进行注册,因为它对登录的工作方式相同。只是想知道是否可以工作。
这是我的代码:
Passport.js
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const myClientId = require("./keys").clientID;
const myClientSecret = require("./keys").clientSecret;
// get the user schema
const User = require("../models/User");
// passport google authentication
module.exports = function (passport) {
passport.use(
new GoogleStrategy(
{
clientID: myClientId,
clientSecret: myClientSecret,
callbackURL: "/auth/google/callback",
},
(accessToken, refreshToken, profile, done) => {
const newUser = new User({
googleId: profile.id,
displayName: profile.displayName,
firstName: profile.name.givenName,
lastName: profile.name.familyName,
image: profile.photos[0].value,
});
User.findOne({ googleId: profile.id })
.then((user) => {
if (user) {
done(null, user);
} else {
newUser.save().then((userd) => {
done(null, userd);
});
}
})
.catch((err) => console.log(err));
}
)
);
// using same strategy again but different callback URL
passport.use(
new GoogleStrategy(
{
clientID: myClientId,
clientSecret: myClientSecret,
callbackURL: "/users/google/callback",
},
(accessToken, refreshToken, profile, done) => {
const newUser = new User({
googleId: profile.id,
displayName: profile.displayName,
firstName: profile.name.givenName,
lastName: profile.name.familyName,
image: profile.photos[0].value,
});
User.findOne({ googleId: profile.id })
.then((user) => {
if (user) {
done(null, false);
} else {
newUser.save().then((userd) => {
done(null, userd);
});
}
})
.catch((err) => console.log(err));
}
)
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
};
app.js
/* initalized passport, session and other stuff here but just showing you the routes and the passport
function in app.js */
require("./config/passport")(passport);
app.use("/auth", require("./routes/auth"));
app.use("/users", require("./routes/users"));
auth.js
const express = require("express");
const passport = require("passport");
const router = express.Router();
//? register and login handle
router.get(
"/google",
passport.authenticate("google", {
scope: ["profile"],
})
);
//? google auth callback
router.get(
"/google/callback",
passport.authenticate("google", {
successRedirect: "/dashboard",
failureRedirect: "/",
})
);
module.exports = router;
users.js
const express = require("express");
const router = express.Router();
const passport = require("passport");
const { ensureAuthenticated, forwardAuth } = require("../config/checkAuth");
//? register page
router.get("/register", forwardAuth, (req, res) => {
res.render("register");
});
//? login page
router.get("/login", forwardAuth, (req, res) => {
res.render("login");
});
//? logout handle
router.get("/logout", (req, res) => {
req.logOut();
res.redirect("/");
});
router.get(
"/google",
passport.authenticate("google", {
scope: ["profile"],
})
);
router.get(
"/google/callback",
passport.authenticate("google", {
successRedirect: "/dashboard",
failureRedirect: "/users/register",
})
);
module.exports = router;
因此,如果用户在 /auth/google 上登录...他将被重定向到注册页面 (/users/register)!不知道为什么
我解决了我的问题。
解决方法其实很简单。只使用相同的 passport.js 文件。
在passport.js
const GoogleStrategy = require("passport-google-oauth20").Strategy;
module.exports = function (passport) {
passport.use("firstUse", new GoogleStrategy(....))
passport.use("secondUse", new GoogleStrategy(...))
}
所以问题是你可以用任何你想要的名字注册策略,然后当你想在路由中处理授权中间件时,你只需这样做:
用户和 auth.js
app.get("/auth/google/callback", passport.authenticate("firstUse"));
app.get("/users/google/callback", passport.authenticate("secondUse"));
只需添加您注册时使用的名称。我认为有必要只使用 passport.authenticate("google") 而不是除 "google" 以外的任何名称。
我试图在我的节点应用程序中使用 passport-google-oauth20 两次,但它不起作用。还在学习护照认证。
问题来了:
我制作了一个用户使用 google(/auth.google) 登录的按钮和一个用户使用 google(/users/google) 注册的按钮。我想要它,以便如果用户已经使用 google 在我的应用程序上注册并且他继续按下“使用 google 注册”按钮,他应该被重定向回注册页面(身份验证失败) .在我的例子中,当我添加一次策略并仅添加一个登录按钮(不注册)时,身份验证有效并且用户被重定向到仪表板。但是,当我在 passport.js 中再次添加策略并且“已注册用户”尝试使用 google 登录时,他被重定向到注册页面(找到使用 google 按钮注册的页面) 而不是仪表板。我知道没有必要做这样的事情,也不需要再次使用相同的 strat 进行注册,因为它对登录的工作方式相同。只是想知道是否可以工作。
这是我的代码:
Passport.js
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const myClientId = require("./keys").clientID;
const myClientSecret = require("./keys").clientSecret;
// get the user schema
const User = require("../models/User");
// passport google authentication
module.exports = function (passport) {
passport.use(
new GoogleStrategy(
{
clientID: myClientId,
clientSecret: myClientSecret,
callbackURL: "/auth/google/callback",
},
(accessToken, refreshToken, profile, done) => {
const newUser = new User({
googleId: profile.id,
displayName: profile.displayName,
firstName: profile.name.givenName,
lastName: profile.name.familyName,
image: profile.photos[0].value,
});
User.findOne({ googleId: profile.id })
.then((user) => {
if (user) {
done(null, user);
} else {
newUser.save().then((userd) => {
done(null, userd);
});
}
})
.catch((err) => console.log(err));
}
)
);
// using same strategy again but different callback URL
passport.use(
new GoogleStrategy(
{
clientID: myClientId,
clientSecret: myClientSecret,
callbackURL: "/users/google/callback",
},
(accessToken, refreshToken, profile, done) => {
const newUser = new User({
googleId: profile.id,
displayName: profile.displayName,
firstName: profile.name.givenName,
lastName: profile.name.familyName,
image: profile.photos[0].value,
});
User.findOne({ googleId: profile.id })
.then((user) => {
if (user) {
done(null, false);
} else {
newUser.save().then((userd) => {
done(null, userd);
});
}
})
.catch((err) => console.log(err));
}
)
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
});
});
};
app.js
/* initalized passport, session and other stuff here but just showing you the routes and the passport
function in app.js */
require("./config/passport")(passport);
app.use("/auth", require("./routes/auth"));
app.use("/users", require("./routes/users"));
auth.js
const express = require("express");
const passport = require("passport");
const router = express.Router();
//? register and login handle
router.get(
"/google",
passport.authenticate("google", {
scope: ["profile"],
})
);
//? google auth callback
router.get(
"/google/callback",
passport.authenticate("google", {
successRedirect: "/dashboard",
failureRedirect: "/",
})
);
module.exports = router;
users.js
const express = require("express");
const router = express.Router();
const passport = require("passport");
const { ensureAuthenticated, forwardAuth } = require("../config/checkAuth");
//? register page
router.get("/register", forwardAuth, (req, res) => {
res.render("register");
});
//? login page
router.get("/login", forwardAuth, (req, res) => {
res.render("login");
});
//? logout handle
router.get("/logout", (req, res) => {
req.logOut();
res.redirect("/");
});
router.get(
"/google",
passport.authenticate("google", {
scope: ["profile"],
})
);
router.get(
"/google/callback",
passport.authenticate("google", {
successRedirect: "/dashboard",
failureRedirect: "/users/register",
})
);
module.exports = router;
因此,如果用户在 /auth/google 上登录...他将被重定向到注册页面 (/users/register)!不知道为什么
我解决了我的问题。
解决方法其实很简单。只使用相同的 passport.js 文件。
在passport.js
const GoogleStrategy = require("passport-google-oauth20").Strategy;
module.exports = function (passport) {
passport.use("firstUse", new GoogleStrategy(....))
passport.use("secondUse", new GoogleStrategy(...))
}
所以问题是你可以用任何你想要的名字注册策略,然后当你想在路由中处理授权中间件时,你只需这样做:
用户和 auth.js
app.get("/auth/google/callback", passport.authenticate("firstUse"));
app.get("/users/google/callback", passport.authenticate("secondUse"));
只需添加您注册时使用的名称。我认为有必要只使用 passport.authenticate("google") 而不是除 "google" 以外的任何名称。