Passport&JWT和谷歌/ Facebook战略 - 我如何结合JWT和谷歌/ Facebook战略?

Vad*_*ico 10 oauth-2.0 facebook-oauth jwt passport.js google-oauth2

这个问题适合任何熟悉的人

  • Node.js的
  • 表达
  • 护照
  • 带护照的JWT认证(JSON Web令牌)
  • Facebook OAuth2.0或Google OAuth2.0

我一直在做一些在线课程,并了解如何做以下两件事:

  1. 使用Passport本地策略+ JWT令牌进行身份验证
  2. 使用Passport Google/Facebook策略+ Cookie /会话进行身份验证.

我试图基本上结合这两门课程的内容.我想使用Google Strategy + JWT身份验证.我想使用JWT而不是cookie,因为我的应用程序将是一个网络/移动/平板电脑应用程序,我需要从不同的域访问api.

我对此有两个问题: 要启动Google/facebook OAuth管道,您需要调用'/ auth/facebook'或'/ auth/google'.两个Oauth流程基本相同,所以当我从现在开始说"/ auth/google"时,我指的是其中之一.现在我遇到的问题是:在客户端,我是否通过href按钮链接或axios/ajax调用调用'/ auth/google'路由?如果我使用href或axios/ajax方法,我仍然会遇到两种解决方案的问题.

href方法问题: 当我将<a>带有href 的标签分配给'/ auth/google'时,身份验证工作完全正常.用户被推送到Google Auth流程,他们登录并调用'/ auth/google/callback'路由.我现在遇到的问题是如何从'/ auth/google/callback'正确地将JWT令牌发送回客户端?

经过大量的谷歌搜索后,我看到人们只是通过重定向查询参数中的oauth回调将JWT传递回客户端.例如:

res.redirect(301, `/dashboard?token=${tokenForUser(req.user)}`);
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,现在我的浏览器历史记录中保存了身份验证功能!我可以注销(破坏localStorage中保存的令牌),然后只需查看我的浏览器URL历史记录,回到查询参数中包含令牌的URL,我会自动再次登录而无需经过谷歌策略!这是一个巨大的安全漏洞,显然是接近它的错误方法.

axios/ajax方法问题: 在我解释这个问题的问题之前,我肯定知道如果我得到这个工作,它将解决我以前的href问题所遇到的所有问题.如果我设法从axios.get()调用中调用'/ google/auth'并在响应正文中接收JWT,我将不会将该令牌作为url param发送,并且它不会保存在浏览器历史记录中!完美对吗?这种方法还存在一些问题:(

尝试调用时,axios.get('/auth/google')我收到以下错误:

在此输入图像描述

我是如何尝试解决问题的:

  • 我在我的npm服务器上安装了cors,并添加app.use(cors());到我的index.js中.
  • 我采取了一个刺,并将" http:// localhost:3000 "添加到Google开发人员控制台中的"授权JavaScript来源".

这些解决方案都没有解决问题,所以现在我真的感到困惑.我想使用axios/ajax方法,但我不确定如何克服这个cors错误.

抱歉这么长的消息,但我真的觉得我必须给你所有的信息,以便你能够正确地帮助我.

再次感谢,期待收到您的来信!

Ram*_*Ali 17

虽然有很好的答案,但我想通过示例添加更多信息。

  • Passport 的 google/facebook 策略是基于会话的,它将用户信息存储在 cookie 中,这是不可取的。所以我们需要先禁用它

要禁用会话,我们需要修改重定向路由器。例如,如果我们有如下所示的重定向路径/google/redirect,我们需要传递{ session: false }对象作为参数。

router.get('/google/redirect', passport.authenticate('google', { session: false }), (req, res)=> {
    console.log(":::::::::: user in the redirect", req.user);
    //GENERATE JWT TOKEN USING USER
    res.send(TOKEN);
})
Run Code Online (Sandbox Code Playgroud)

那么这个用户是从哪里来的呢?这个用户来自passport的回调函数。在前面的代码段中,我们添加了passport.authenticate(....)这个中间线启动了passport 的google-strategy 回调来处理用户。例如

passport.use(
    new GoogleStrategy({
        callbackURL: '/google/redirect',
        clientID: YOUR_GOOGLE_CLIENT_ID
        clientSecret: YOUR_GOOGLE_SECRET_KEY
    }, 
    (accessToken, refreshToken, profile, done)=>{
        console.log('passport callback function fired');

        // FETCH USER FROM DB, IF DOESN'T EXIST CREATE ONE

        done(null, user);

    })
)
Run Code Online (Sandbox Code Playgroud)

就是这样。我们成功地结合了 JWT 和 Google/Facebook 策略。


vbl*_*nka 15

我用这种方式解决了这个问题:

  1. 在前端(可以是移动应用程序)我向谷歌(或Facebook)提出登录请求,在用户选择了他的帐户并登录后,我得到了包含谷歌身份验证令牌和基本用户信息的回复.
  2. 然后我将google身份验证令牌发送到后端,我的API又向Google API发送了一个请求以确认该令牌.(见第5步)
  3. 成功请求后,您将获得基本的用户信息和电子邮件.此时,您可以假设用户通过Google登录是好的,因为谷歌检查返回它没关系.
  4. 然后,您只需使用该电子邮件注册或登录用户并创建该JWT令牌.
  5. 将令牌返回给您的客户端,并将其用于将来的请求.

我希望它有所帮助.我实施了多次,它显示了一个很好的解决方案.