第 1 步:创建您的初始node.js 应用程序并安装以下包,因为我们将在我们的项目中使用它
npm i express,jsonwebtoken,passport,passport-google-oauth20,dotenv
第 2 步:在 google developer console 中创建一个新项目并获取 google client id 和 secret。 将此配置添加到 .env 文件并添加 jwt 秘密,使用此命令创建一个随机秘密。
openssl rand -base64 32
第 3 步:在您的应用中创建文件 passport.js。
const passport = require("passport");
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const jwt = require("jsonwebtoken");
passport.use(
new GoogleStrategy(
{
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "http://localhost:5000/api/auth/googleRedirect",
},
async function (accessToken, refreshToken, profile, done) {
return done(null, profile);
}
)
);
第 4 步:创建 auth.route.js 文件
const jwt = require("jsonwebtoken");
const express = require("express");
const router = express.Router();
const passport = require("passport");
/* 这是用户单击 Google 登录按钮时将被重定向到的路由。*/
router.get(
"/login/google",
passport.authenticate("google", { scope: ["profile", "email"] })
);
// GOOGLE LOGIN CALLBACK
router.get(
"/googleRedirect",
passport.authenticate("google"),
async (req, res) => {
console.log("req.user", req.body);
const users = {
firstName: req.user.displayName,
lastName: req.user.name.familyName,
email: req.user.emails[0].value,
imgURL: req.user.photos[0].value,
lastLogin: Date.now(),
};
/* 检查用户是否存在于数据库中的函数。 如果是,它返回用户。 如果没有,它会创建一个新用户。 */
await Users.findOne({ email: users.email }, async (err, user) => {
if (err) {
done(err, false, {
message: "Something went wrong with Google OAuth",
});
}
if (user) {
// 用户已经存在于我们的数据库中
console.debug("User already exists in our database");
// 更新上次登录时间戳
user.lastLogin = Date.now();
Users(user).save();
let token = jwt.sign(
{
data: users,
},
process.env.JWT_SECRET,
{ expiresIn: "24h" }
); // expiry in 24 hours
res.cookie("jwt", token);
res.redirect(process.env.CLIENT_AUTH_REDIRECT_URL);
} else {
Users(users).save();
let token = jwt.sign(
{
data: users,
},
process.env.JWT_SECRET,
{ expiresIn: "24h" }
); // expiry in 24 hours
res.cookie("jwt", token);
res.redirect(process.env.CLIENT_AUTH_REDIRECT_URL);
}
});
}
);
module.exports = router;
第 5 步:创建一个中间件控制器来验证并从数据库中获取详细信息。
const jwt = require("jsonwebtoken");
const userModel = require("../model/user.model");
//获取当前用户详情的中间件
router.get("/current_user", verifyStudent, currentuser);
exports.verifyStudent = async (req, res, next) => {
const jwt_t = req.headers.cookie;
if (jwt_t) {
const token = jwt_t.split("=")[1].split(";")[0];
jwt.verify(token, process.env.JWT_SECRET, async (err, user) => {
if (err) {
return res.status(403).json("Token is not valid!");
}
const user = await userModel.findOne({ email: user.data.email });
if (!user) {
return res.status(403).json("User not found!");
}
req.user = user;
next();
});
} else {
return res.status(401).json("You are not authenticated!");
}
};
exports.currentuser = async (req, res) => {
if (req.user) {
res.status(200).json({
message: "User is logged in successfully!",
success: true,
user: req.user,
});
} else {
res.status(401).json({
message: "Invalid user id!",
success: false,
});
}
};