使用passport-apple库在nestjs中进行苹果登录未返回id_token。

huangapple go评论61阅读模式
英文:

Signin with apple with passport-apple library not returning id_token in nestjs

问题

我正在使用NestJS和"passport-apple"库设置苹果登录。第一次登录返回一个包含"state"、"code"和"user"的数据对象,但没有id_token。

后续的登录只返回包含"state"和"code"的数据对象。

我理解苹果在后续登录中不会返回用户对象,但问题是"state"和"code"不是唯一的用户标识,因为每次登录请求返回的"state"和"code"值都不同。现在我无法在用户每次使用苹果登录时识别用户。

以下是我的策略配置:

import { Inject, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from 'passport-apple';

import { readFileSync } from 'fs';

@Injectable()
export class AppleStrategy extends PassportStrategy(Strategy, 'apple') {
  constructor(configService: ConfigService) {
    super({
      clientID: configService.get<string>('APPLE_CLIENT_ID'),
      teamID: configService.get<string>('APPLE_TEAM_ID'),
      keyID: configService.get<string>('APPLE_KEY_ID'),
      key: readFileSync(
        __dirname + '/../../../apple_secret/apple_secret_key.p8',
      ),
      callbackURL: configService.get<string>('APPLE_CALLBACK_URL'),
      passReqToCallback: false,
      response_type: 'code id_token',
      scope: ['name', 'email'],
    });
  }
}

第一次登录响应体:

{
"state": ".......",
"code": "..............................................",
"user": "{\"name\":{\"firstName\":\"First_Name\",\"lastName\":\"Last_Name\"},\"email\":\"Email\"}"
}

后续响应体:

{
"state": ".......",
"code": ".............................................."
}
英文:

I am setting up Apple Login with the "passport-apple" library using NestJS. The first login returns a data object with "state," "code," and "user," but no id_token.

Subsequent logins return data objects containing only "state" and "code."

I understand that Apple does not return a user object in the subsequent login, but "code" and "state" are not unique to the user as the value returned for "state" and "code" is different at any login request. Now there is no way for me to identify the user each time the user makes a login request with Apple.

below is my strategy configuration:

import { Inject, Injectable } from &#39;@nestjs/common&#39;;
import { ConfigService } from &#39;@nestjs/config&#39;;
import { PassportStrategy } from &#39;@nestjs/passport&#39;;
import { Strategy } from &#39;passport-apple&#39;;

import { readFileSync } from &#39;fs&#39;;

@Injectable()
export class AppleStrategy extends PassportStrategy(Strategy, &#39;apple&#39;) {
  constructor(configService: ConfigService) {
    super({
      clientID: configService.get&lt;string&gt;(&#39;APPLE_CLIENT_ID&#39;),
      teamID: configService.get&lt;string&gt;(&#39;APPLE_TEAM_ID&#39;),
      keyID: configService.get&lt;string&gt;(&#39;APPLE_KEY_ID&#39;),
      key: readFileSync(
        __dirname + &#39;/../../../apple_secret/apple_secret_key.p8&#39;,
      ),
      callbackURL: configService.get&lt;string&gt;(&#39;APPLE_CALLBACK_URL&#39;),
      passReqToCallback: false,
      response_type: &#39;code id_token&#39;,
      scope: [&#39;name&#39;, &#39;email&#39;],
    });
  }

}

My first login response body:

{
&quot;state&quot;: &quot;.......&quot;,
&quot;code&quot;: &quot;..............................................&quot;,
&quot;user&quot;: &quot;{&quot;name&quot;:{&quot;firstName&quot;:&quot;First_Name&quot;,&quot;lastName&quot;:&quot;Last_Name&quot;},&quot;email&quot;:&quot;Email&quot;}&quot;
}

My subsequent respnse body:

{
&quot;state&quot;: &quot;.......&quot;,
&quot;code&quot;: &quot;..............................................&quot;
}

答案1

得分: 1

我能够通过使用不同的库来解决这个问题。我使用了 @arendajaelu/nestjs-passport-apple。

$ npm install @arendajaelu/nestjs-passport-apple

我的 AppleStrategy:

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy } from '@arendajaelu/nestjs-passport-apple';
import { ConfigService } from '@nestjs/config';
import { readFileSync } from 'fs';

@Injectable()
export class AppleStrategy extends PassportStrategy(Strategy, 'apple') {
  constructor(config: ConfigService) {
    super({
      clientID: config.get<string>('APPLE_CLIENT_ID'),
      teamID: config.get<string>('APPLE_TEAM_ID'),
      keyID: config.get<string>('APPLE_KEY_ID'),
      keyFilePath: readFileSync(
        __dirname + '/../../../apple_secret/apple_secret_key.p8',
      ),
      callbackURL: config.get<string>('APPLE_CALLBACK_URL'),
      passReqToCallback: false,
      scope: ['email', 'name'],
    });
  }
}

响应:

{
  "code": "..............................................",
  "id_token": "..............................................",
  "user": "{\"name\":{\"firstName\":\"First_Name\",\"lastName\":\"Last_Name\"},\"email\":\"Email\"}"
}

注意:用户对象仅在首次登录时返回;随后的登录仅返回 code 和 id_token。

英文:

I was able to resolve this by using a diffrent libeary. I use @arendajaelu/nestjs-passport-apple

$ npm install @arendajaelu/nestjs-passport-apple

My AppleStrategy:

import { Injectable } from &#39;@nestjs/common&#39;;
import { PassportStrategy } from &#39;@nestjs/passport&#39;;
import { Strategy } from &#39;@arendajaelu/nestjs-passport-apple&#39;;
import { ConfigService } from &#39;@nestjs/config&#39;;
import { readFileSync } from &#39;fs&#39;;

@Injectable()
export class AppleStrategy extends PassportStrategy(Strategy, &#39;apple&#39;) {
  constructor(config: ConfigService) {
    super({
      clientID: config.get&lt;string&gt;(&#39;APPLE_CLIENT_ID&#39;),
      teamID: config.get&lt;string&gt;(&#39;APPLE_TEAM_ID&#39;),
      keyID: config.get&lt;string&gt;(&#39;APPLE_KEY_ID&#39;),
      keyFilePath: readFileSync(
        __dirname + &#39;/../../../apple_secret/apple_secret_key.p8&#39;,
      ),
      callbackURL: config.get&lt;string&gt;(&#39;APPLE_CALLBACK_URL&#39;),
      passReqToCallback: false,
      scope: [&#39;email&#39;, &#39;name&#39;],
    });
  }
}

Response:

{
&quot;code&quot;: &quot;..............................................&quot;,
&quot;id_token&quot;: &quot;..............................................&quot;,
&quot;user&quot;: &quot;{&quot;name&quot;:{&quot;firstName&quot;:&quot;First_Name&quot;,&quot;lastName&quot;:&quot;Last_Name&quot;},&quot;email&quot;:&quot;Email&quot;}&quot;
}

NB: The user object is only returned on the first login; the subsiquent login returns code and id_token only.

huangapple
  • 本文由 发表于 2023年2月19日 00:34:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75494769.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定