谷歌在 NestJS 后端使用 PassportStrategy 登录无法由 React WebApp 调用

Posted

技术标签:

【中文标题】谷歌在 NestJS 后端使用 PassportStrategy 登录无法由 React WebApp 调用【英文标题】:Google login with PassportStrategy in NestJS backend not working called by React WebApp 【发布时间】:2021-05-20 20:21:25 【问题描述】:

我已经在 NestJS 后端使用 PassportStrategy 实现了 Google 登录(NestJS 后端开发基于本指南:https://medium.com/@nielsmeima/auth-in-nest-js-and-angular-463525b6e071)。

@Get('google')
@UseGuards(AuthGuard('google'))
googleLogin()

    // initiates the Google OAuth2 login flow


@Get('google/callback')
@UseGuards(AuthGuard('google'))
googleLoginCallback(@Req() req, @Res() res)

    // handles the Google OAuth2 callback
    const jwt: string = req.user.jwt;
    if (jwt)
        return res.status(HttpStatus.OK).cookie('jwt', jwt, 
            httpOnly: true
        ).redirect('/');
    else 
        res.redirect('http://localhost:4200/login/failure');

使用@UseGuards(AuthGuard('google')) 应该启动google登录:

super(
        clientID    : 'XXX',     // <- Replace this with your client id
        clientSecret: 'XXX', // <- Replace this with your client secret
        callbackURL : 'http://myapp.herokuapp.com/auth/google/callback',
        passReqToCallback: true,
        scope: ['profile']
    )

如果我将调用 auth/google 放在浏览器的地址栏中,它就可以工作。

如果我从 React WebApp 调用方法 auth/google 它将不起作用,并且网络请求是屏幕截图中的请求。我没有响应数据。

App Requests

Google Detail

似乎回调没有启动,但“passReqToCallback: true”有效。

响应前端请求:

fetch("http://<url>/auth/google", 
  method: "GET",
  mode: 'no-cors',
  headers: 
    'Content-Type': 'application/json',
    'Accept': 'application/json'
  
)
.then(
  (result) => 
        if (result) 
          history.push(
            pathname: '/home'
          );
        
  ,
  (error) => 
    
  
);

登录顺利时的后端日志:

2021-02-18T10:34:02.724706+00:00 heroku[路由器]: at=info method=GET path="/auth/google/" host=myapp.herokuapp.com request_id=310ac45a-3657-4c5f -96dc-f0a1350429db fwd="93.146.33.170" dyno=web.1 connect=1ms service=10ms status=302 bytes=371 protocol=http

2021-02-18T10:34:03.321194+00:00 app[web.1]:

2021-02-18T10:34:03.321209+00:00 app[web.1]: id: 'XXX',

2021-02-18T10:34:03.321210+00:00 app[web.1]: displayName: 'XXX',

登录失败时的后端日志:

2021-02-18T10:36:29.284759+00:00 heroku[路由器]: at=info method=GET path="/auth/google" host=myapp.herokuapp.com request_id=2f56f65b-9236-4710- b029-dd973ec0c9a3 fwd="54.187.137.25" dyno=web.1 connect=0ms service=3ms status=302 bytes=371 protocol=http

没有别的

有什么想法吗?你能帮帮我吗?

谢谢。

【问题讨论】:

您需要显示更多代码,说明什么可以设置 cookie,什么不可以。你打什么电话?为什么这被标记为“nestjs”?您是否使用它作为您的后端框架? 我尝试添加更多细节。 【参考方案1】:

您实现 google 登录的方式对于全栈应用程序很有用。由于您使用的是单独的 React 应用程序(我们称之为 SPA),因此您需要进行一些更改。首先,您的后端不需要/google 端点。该部分应由 SPA 完成。用户使用 google 登录后,它应该再次将他重定向到 SPA。此重定向将在查询参数中为您提供用户信息和访问令牌。

只有这样,您才会将该信息转发到后端的 /google/callback 路由。您已经使用google auth 保护进行了 google 令牌验证,所以唯一剩下的就是使用 google 提供给您的信息来登录用户。我想在你的情况下这意味着生成一个 JWT。不要使用谷歌提供的令牌。生成您自己的 JWT。

来自谷歌documentation:

如果您将 Google 登录用于与后端服务器通信的应用或网站,您可能需要识别服务器上当前登录的用户。要安全地执行此操作,请在用户成功登录后,使用 HTTPS 将用户的 ID 令牌发送到您的服务器。然后,在服务器上,验证 ID 令牌的完整性,并使用令牌中包含的用户信息来建立会话或创建新帐户。

【讨论】:

谢谢,但没有解决。我尝试添加更多细节。 尝试在服务器端不重定向。由于您正在发出 ajax 请求,因此不应依赖服务器重定向。相反,成功时在前端重定向。 相同。我认为这是后端登录流程中的内容。 我想我现在明白你的问题了。我已经编辑了我的答案。【参考方案2】:

更改调用 api 的方式,像普通链接一样调用它,而不是 ajax 请求。

&lt;a href=`http://$url/auth/google`&gt;Google Login&lt;/a&gt;

【讨论】:

以上是关于谷歌在 NestJS 后端使用 PassportStrategy 登录无法由 React WebApp 调用的主要内容,如果未能解决你的问题,请参考以下文章

PJzhang:谷歌在中国大陆可以使用的部分服务

谷歌在 Android 上使用集群映射自定义标记图标

谷歌在 Angular 7 中使用 .NET Core API 登录

为啥谷歌在我得到的美元上花了 0.3 [关闭]

在 NestJs 中验证 Google JWT

防止谷歌在Angular2中自动填写表格[重复]