yikart/AiToEarn · error · BadRequestException

缺少必要的参数

Error message

缺少必要的参数

What it means

A BadRequestException raised by the handleAuthCallback controller when TikTok's redirect to the callback URL omits the code or state query parameters. Both are required: code exchanges for tokens, state correlates the request with the pending authorization in Redis.

Source

Thrown at project/aitoearn-electron/server/src/modules/plat/tiktok/tiktok.controller.ts:53

    return this.tikTokAuthService.getAuthorizationUrl(systemToken.id, mail);
  }

  /**
   * TikTok OAuth2回调处理
   */

  @ApiOperation({ summary: 'TikTok OAuth2回调处理' })
  @Public()
  @ApiQuery({ name: 'code', type: String, description: 'OAuth2授权码' })
  @ApiQuery({ name: 'state', type: String, description: '状态码' })
  @Get('auth/callback')
  async handleAuthCallback(
    @Query('code') code: string,
    @Query('state') state: string,
    @Res() res: Response,
  ) {
    if (!code || !state) {
      throw new BadRequestException('缺少必要的参数');
    }
    console.log(code, state);

    try {
      // 处理授权回调
      const results = await this.tikTokAuthService.handleAuthorizationCallback(code, state);
      const render_msg = {
        message: "授权成功! 这里是添加账号成功后的前端页面," ,
        datas: results
      };

      return res.render('google/index', render_msg);
    } catch (error) {
      console.error('处理TikTok授权回调失败:', error.response?.data || error.message);
      throw new BadRequestException(`处理授权回调失败: ${error.response?.data?.error?.message || error.message}`);
    }
  }

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Inspect the callback URL for error/error_description query params (user denied access) and handle them with a friendly message before checking code/state.
  2. Re-initiate the OAuth flow from /tiktok/auth-url to get a fresh code and state.
  3. Verify the redirect_uri registered on the TikTok app has no conflicting query string and that the server does not strip query params.
  4. On the client, never call the callback endpoint directly; always follow TikTok's redirect.

Example fix

// before
if (!code || !state) {
  throw new BadRequestException('缺少必要的参数');
}
// after
if (error) {
  return res.redirect(`/oauth/result?status=denied&reason=${encodeURIComponent(error_description || error)}`);
}
if (!code || !state) {
  return res.redirect('/oauth/result?status=failed&reason=missing_params');
}
Defensive patterns

Strategy: validation

Validate before calling

// on the callback page, before invoking the API
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const state = params.get('state');
if (!code || !state) {
  const err = params.get('error_description') || params.get('error') || 'missing code/state';
  showDeniedMessage(err); // user likely cancelled consent
}

Type guard

function hasOAuthCallbackParams(q: Record<string, string | undefined>): q is Record<'code' | 'state', string> {
  return typeof q.code === 'string' && q.code.length > 0 && typeof q.state === 'string' && q.state.length > 0;
}

Try / catch

try {
  await api.completeTikTokAuth(code, state);
} catch (e) {
  if ((e as any).status === 400 && /缺少必要的参数/.test((e as Error).message)) {
    return restartTikTokOAuth();
  }
  throw e;
}

Prevention

When it happens

Trigger: The user lands on /tiktok/callback without ?code=...&state=... — e.g. the user cancelled/failed consent so TikTok redirects back with error parameters instead of code, the redirect_uri's query handling strips parameters, or someone hits the callback URL manually.

Common situations: User denied permission on TikTok's consent screen (redirect contains error=access_denied, no code), bookmarked/stale callback link, redirect_uri registered with a query string that collides with OAuth parameters, proxy rewriting the URL.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/96136d7de4111ad5. Report an issue: GitHub.