这个问题适合任何熟悉
的人我一直在做一些在线课程,并了解如何做以下两件事:
我试图将这两门课程的内容基本结合起来。我想使用Google Strategy + JWT身份验证。我想使用JWT而不是cookie,因为我的应用程序将是一个网络/移动/平板电脑应用程序,我需要从不同的域访问api。
我对此有两个问题: 要启动Google / facebook OAuth管道,您需要拨打' / auth / facebook'或' / auth / google'。 Oauth流程的工作基本相同,所以当我说' / auth / google'从现在开始,我指的是其中之一。现在我遇到的问题是:在客户端,我是否打电话给' / auth / google'路线与href按钮链接或axios / ajax呼叫?如果我使用href或axios / ajax方法,我仍然会遇到两种解决方案的问题。
href接近问题:
当我将带有href的<a>
代码分配给&#39; / auth / google&#39;身份验证工作完全正常。用户通过Google Auth流程进行推送,他们会登录并使用&#39; / auth / google / callback&#39;路线被召唤。我现在遇到的问题是如何从&#39; / auth / google / callback&#39;中正确地将JWT令牌发送回客户端?
经过大量的谷歌搜索后,我看到人们只是通过重定向查询参数中的oauth回调将JWT传递回客户端。例如:
res.redirect(301, `/dashboard?token=${tokenForUser(req.user)}`);
我遇到的问题是,现在我的浏览器历史记录中保存了身份验证功能!我可以注销(破坏localStorage中保存的令牌),然后只需查看我的浏览器URL历史记录,回到查询参数中包含令牌的URL,我会自动再次登录而无需经过谷歌策略!这是一个巨大的安全漏洞,显然是接近它的错误方法。
axios / ajax方法问题: 现在在我解释这个问题的问题之前,我肯定知道如果我得到这个工作,它将解决我以前的href问题所遇到的所有问题。如果我设法拨打&#39; / google / auth&#39;从axios.get()调用并在响应体中接收JWT,我不会将令牌作为url param发送,并且它不会保存在浏览器历史记录中!完美对吗?这种方法还存在一些问题:(
尝试拨打axios.get('/auth/google')
时出现以下错误:
我是如何尝试解决问题的:
app.use(cors());
添加到我的index.js中。 这些解决方案都没有解决问题,所以现在我真的感到困惑。我想使用axios / ajax方法,但我不确定如何克服这个错误。
很抱歉这么长的消息,但我真的觉得我必须给你所有的信息才能帮助我。
再次感谢,期待收到你的来信!
答案 0 :(得分:12)
我用这种方式解决了这个问题:
我希望它有所帮助。我实施了多次,它表现得很好。
答案 1 :(得分:1)
尽管答案很好,但我想通过示例添加更多信息。
要禁用会话,我们需要修改重定向路由器。例如,如果我们具有如下所示的重定向路径 / 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);
})
那么这个用户来自哪里?该用户来自护照的回叫功能。在上一个代码段中,我们添加了 passport.authenticate(....)。此中间线可启动护照的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);
})
)
就是这样。我们已经成功地将JWT和Google / Facebook策略结合在一起。
答案 2 :(得分:-1)
我找到的解决方案是在弹出窗口(window.open
)中执行OAuth流程,它使用预定义的回调函数在成功进行身份验证后将令牌传递给前端。
以下是本教程中的相关代码示例: https://www.sitepoint.com/spa-social-login-google-facebook/
这是从前端调用的预定义回调和初始打开方法:
window.authenticateCallback = function(token) {
accessToken = token;
};
window.open('/api/authentication/' + provider + '/start');
以下是您的OAuth回调网址应在成功进行身份验证后返回的内容(这是弹出窗口中的最后一步/页面):
<!-- src/public/authenticated.html -->
<!DOCTYPE html>
<html>
<head>
<title>Authenticated</title>
</head>
<body>
Authenticated successfully.
<script type="text/javascript">
window.opener.authenticateCallback('{{token}}');
window.close();
</script>
</body>
</html>
您的令牌现在可用于您的前端预定义回调函数,您可以在其中轻松将其保存在localStorage中。
我想,您可以在同一个窗口中执行OAuth流程(无弹出窗口)并返回一个HTML页面(类似于上面的内容),它只保存令牌并立即将用户重定向到仪表板。
但是,如果您的前端域与api / auth服务器不同,则可能需要使用一次性时间敏感令牌(由生成者生成)从api / auth服务器重定向到前端。您的api / auth服务器),您的前端可以用来调用和接收(使用axios)您的实际令牌。这样您就不会遇到浏览器历史记录安全问题。