2

我正在使用 expressJs 和护照进行身份验证。我正在使用 Google Oauth2.0 通过标准 Passport GoogleStrategy 登录。在客户端,我使用 axios 向服务器发送登录请求。我的登录路线是:

router.get(
    "/google",
    passport.authenticate("google", { scope: ["profile", "email"] }));

router.get(
    "/google/callback",
    passport.authenticate("google", { failureRedirect: "/"}),
    function(req, res) {

        const token = jwt.sign({id: req.user.id}, configAuth.secretKey);
        console.log("generated token: ", token);
        res.json({success: true, token: 'bearer ' + token});

    }
);

我正在使用回调中的用户信息来生成我想要发送给客户端的 JWT。

在客户端,我使用 axios 发送请求并获取 JWT 并将其存储在 localstore 中。

axios.get('http://localhost:3001/google')
  .then((result) => {
    console.log("result", result);
    localStorage.setItem('jwtToken', result.data.token);
  })
  .catch((error) => {
    // if(error.response.status === 401) {
    //   this.setState({ message: 'Login failed. Username or password not match' });
    // }
    console.log("Login error", error);
  });

但是 Axios 不会等待重定向发生并返回一个带有 Loading... 消息的 HTML 文档。如果您尝试在浏览器中访问 API,它会返回所需的 JSON 对象。有没有办法等待重定向。我应该使用另一个库来发送登录请求吗?

我尝试将令牌作为 url 参数发送

res.redirect()

但是客户端和服务器位于不同的端口,所以它不起作用。还有另一种方法吗?

4

2 回答 2

0

Google 的 OAuth2 路径会重定向您的浏览器,导致页面重新加载,在完成之前几次。结果,您的客户端代码,

axios.get('http://localhost:3001/google')
  .then((result) => {
    console.log("result", result);
    localStorage.setItem('jwtToken', result.data.token);
  })...

永远不会到达.then()街区。您可能会在浏览器中看到它;您单击按钮或导航到'http://localhost:3001/google',您的localhost:3001服务器会将您的浏览器重定向到 Google 登录页面。现在您的浏览器在登录页面,它已经不记得axios.get上面的语句了——网页代码已经消失了。

您需要在服务器发送响应的客户端代码中处理 JWT

axios.get('http://localhost:3001/google/callback').

这是您的浏览器在 OAuth2 路径中的最后一站——一旦您到达那里,您将不会再次被重定向。您可以将您的axios.get函数放在该客户端代码中。

于 2018-08-21T13:54:05.060 回答
0

如果您还没有解决问题,有一个解决方法是在 passportjs 上使用“googleTokenStategy”而不是 googleOAuth。这样你就可以使用 react 的 GoogleLogin 插件从前端接收访问令牌,并通过 axios.post 将其发送到后端链接,然后设置 jwt。参考这里

于 2019-01-25T05:47:18.907 回答