任何人都可以与护照谷歌 oauth2 集成分享下一个 js 的例子吗?

IT技术 reactjs next.js
2021-05-05 18:22:38

如果您有任何使用护照 google oauth2 的nextjs项目的代码示例,请分享。网上有一些仅使用 nodejs 的示例,但路由、中间件和回调的机制与 nextjs 不同,我还没有找到工作示例。

我有以下代码,但收到 CORS 错误。我在本地主机上看过带有 google auth 演示的 youtube 视频。我创建的凭据也使用 localhost。

\lib\Passport.js

import passport from 'passport';

import { Strategy as GoogleStrategy } from 'passport-google-oauth20';

passport.serializeUser((user, done) => {
  done(null, user._id);
});

passport.deserializeUser((req, id, done) => {
  req.db
    .collection('users')
    .findOne({ _id: id })
    .then((user) => done(null, user));
});

passport.use(new GoogleStrategy({
  clientID: process.env.GOOGLE_CLIENT,
  clientSecret: process.env.GOOGLE_SECRET,
  callbackURL: process.env.WEB_URI+"/users/callback/google",
  passReqToCallback: true,
},
function(accessToken, refreshToken, profile, cb) {
  // User.findOrCreate({ googleId: profile.id }, function (err, user) {
  //   return cb(err, user);
  // });
  console.log("profile below")
  console.log(profile)
}
));

export default passport;

\pages\login.js 带按钮 - “使用 Google 登录”

  <Button
  variant="outlined"
  color="secondary"
  startIcon={">"}
  onClick={(event) => {
    googleLogin(event) }}
  >
    Login using Google
  </Button>

和 \pages\login.js 中的功能

  async function googleLogin(e) {
    const res = await fetch('/api/authGoogle', {
      method: 'GET',
      headers: { 'Content-Type': 'application/json' },
    })
    console.log(res);
    return;
  }

而 \pages\api\authGoogle.js

import nextConnect from 'next-connect';
import middleware from '../../middlewares/middleware';
import passport from '../../lib/passport';

const handler = nextConnect();

handler.use(middleware);

handler.get(passport.authenticate("google", {
  scope: ['profile', 'email', 'openid'], 
}))

handler.delete((req, res) => {
  req.logOut();
  res.status(204).end();
});

export default handler;

我没有的是代码users/callback/google,我不知道该写什么。官方的passportjs 示例仅使用nodejs 并且很难遵循,因此任何使用next js 的示例将来都会对我和其他人有所帮助。

4个回答

经过很多时间的挣扎,我自己想出了一些零碎的东西。

步骤 1 对于 Oauth,我们必须直接使用按钮/链接链接到提供者。我们不能使用先进入 api 的 fetch api 调用。

不管用 await fetch('/api/authGoogle

将工作 href="/api/authGoogle

第2步

在 api/authGoogle 中需要调用passport.authenticate。 handler.get(passport.authenticate("google", {scope: ['profile', 'email']}));

第 3 步

在passport.js 或任何你拥有所有策略的地方

passport.use(new GoogleStrategy({
  clientID: process.env.GOOGLE_CLIENT,
  clientSecret: process.env.GOOGLE_SECRET,
  callbackURL: process.env.WEB_URI+"/api/auth/callback/google",
  passReqToCallback: true,
},   
async (req, accessToken, refreshToken, profile, done) => {
  console.log(profile)
  // add code here to check if user exists in database or create a new one

它的工作方式是 /api/auth/callback/google 传递您在浏览器 url 中看到的代码 (code=...)。详细信息然后从回调传递并可用于console.log(profile)上面。

步骤4

回调文件/api/auth/callback/google应如下所示。我只是重定向到主页,但您可以在此文件中设置浏览器 cookie。如果您想这样做,请安装“cookies”,这是一个非常受欢迎的库。

handler.get(passport.authenticate("google"), (req, res) => {
  res.writeHead(302, {
    'Location': '/'
  });
  res.end();
})

这里再次重复了passport.authenticate,但它在步骤2 中。那是因为需要使用代码来使用上面的行获取配置文件信息。

当我尝试使用时res.writeHead,由于某种原因 next-connect 挂起并且请求永远不会解决。我只是用以下代码替换了它,一切都按预期工作:

res.status(302)
res.setHeader('Location', '/')
res.end()

也许这会帮助别人!

首先,我为“答案”深表歉意,但我是堆栈溢出的新手,无权评论您的原始问题,因为显然我缺乏声誉(愚蠢的恕我直言)无论如何,我也在研究与 Next.js 的集成,接下来-与 Passport.js 连接,我也得出结论,您不能使用 afetch()甚至 axios 请求来访问 api 端点并启动通行证。

显然,您必须将您的用户直接发送到端点 ( /api/login)之上,然后当用户被重定向回来时,点击另一个 api 端点(如/api/login/return),然后您就可以成功地从第三方站点获取配置文件。

尝试在端点上进行提取时,我也收到了 CORS 问题。我尝试在 next-connect 中使用 cors() npm 库以及手动插入标题,如下所示:

export default nextConnect()        
    .use((req, res, next) => {      
      req.headers["Access-Control-Allow-Origin"] = "*";
      req.headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS, PUT, PATCH, DELETE";
      req.headers["Access-Control-Allow-Headers"] = "x-access-token, Origin, X-Requested-With, Content-Type, Accept";
      next();
    })
    .use(passport.initialize())
    .use(passport.authenticate('google', { session: false }))   

我知道这是不安全的,但只是尝试了最后的选择以使其正常工作。您知道让用户直接访问 /api/ 端点以使其工作是否“不好”吗?真的想弄清楚这一点,任何回应表示赞赏。