You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NestJS实现Google与Twitch多认证及账号关联技术问询

NestJS 多第三方账号关联方案实现

需求背景

在NestJS中实现基于Google和Twitch的多第三方认证,不采用本地策略,不存储用户个人凭据。核心需求是允许用户关联两个平台账号,以此解锁更多功能。

已实现基础代码

Google认证策略(google.strategy.ts)

// google.strategy.ts

@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
  constructor(
    private userService: UsersService,
    private configService: ConfigService,
  ) {
    super({
      clientID: configService.get<string>('GOOGLE_ID'),
      clientSecret: configService.get<string>('GOOGLE_SECRET'),
      callbackURL: `${configService.get<string>(
        'BASE_URL_APP',
      )}/auth/google/callback`,
      scope: ['email', 'profile'],
    });
  }

  async validate(
    accessToken: string,
    refreshToken: string,
    profile: any,
    cb: Function,
  ): Promise<any> {
    let user = await this.userService.findOneByGoogleProviderId(profile.id);

    if (!user) {
      user = await this.userService.create({
        creatorsFollowed: [],
        providerAccess: [
          {
            accessToken: accessToken,
            platform: Platform.GOOGLE,
            providerUserId: profile.id,
            refreshToken: refreshToken,
            email: profile['_json']['email'],
          },
        ],
        firstname: profile['_json']['given_name'],
        lastName: profile['_json']['family_name'],
      });
    }

    return cb(null, user);
  }
}

Auth控制器中的Google认证端点

@Get('google')
  @UseGuards(AuthGuard('google'))
  async googleAuth() {
  }

  @Get('google/callback')
  @UseGuards(AuthGuard('google'))
  async googleAuthCallback(@Req() req) {

    const providerPurgedData = req.user.providerAccess.map(
      ({ accessToken, refreshToken, ...keepAttrs }) => keepAttrs,
    );

    const payload = {
      providersData: providerPurgedData,
      firstname: req.user?.firstname,
      lastname: req.user?.lastname,
    };
    return { accessToken: this.jwtService.sign(payload) };
  }

新增需求与初始尝试

需要复用现有端点,实现:当用户携带其他平台(如Twitch)的有效JWT访问Google/Twitch认证端点时,不生成新令牌,仅在数据库中关联两个账号。

最初尝试给google/callback和twitch/callback添加中间件,但不知道如何正确验证JWT,也考虑过重写Guard。初始中间件代码如下:

// middleware
import { Injectable, NestMiddleware } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Request, Response } from 'express';

@Injectable()
export class LinkProviderAccountMiddleware implements NestMiddleware {
  constructor(private jwtService: JwtService) {}
  use(req: Request, res: Response, next: () => void) {
    const bearer = req.headers['authorization'].split(' ')[1];

    if (this.jwtService.verify(bearer)) {
      // link account
      res.status(200).json({ msg: 'account linked' });
    }
    next();
  }
}

更新解决方案(2023/06/25)

最终通过中间件结合策略配置实现需求,更新后的代码如下:

验证用户登录状态的中间件

//middleware
import {
  Injectable,
  NestMiddleware,
  UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Request, Response } from 'express';

@Injectable()
export class CheckUserLoggedInMiddleware implements NestMiddleware {
  constructor(private jwtService: JwtService) {}

  use(req: Request, res: Response, next: () => void) {
    const token = req.headers.authorization?.split(' ')[1];

    if (token) {
      try {
        const decoded = this.jwtService.verify(token);

        req.user = decoded;

        return next();
      } catch (error) {
        throw new UnauthorizedException();
      }
    }
    next();
  }
}

更新后的Google策略

// google.strategy
@Injectable()
export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
  constructor(
    private userService: UsersService,
    private configService: ConfigService,
  ) {
    super({
      clientID: configService.get<string>('GOOGLE_ID'),
      clientSecret: configService.get<string>('GOOGLE_SECRET'),
      callbackURL: `${configService.get<string>(
        'BASE_URL_APP',
      )}/auth/google/callback`,
      scope: ['email', 'profile'],
      passReqToCallback: true, // 新增配置
    });
  }
}

现在用户携带有效JWT调用Twitch或Google认证端点时,策略可以从请求中获取到用户信息,进而完成账号关联操作。

内容的提问来源于stack exchange,提问作者Yokido

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 17:30:31