英文:
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 '@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'],
});
}
}
My first login response body:
{
"state": ".......",
"code": "..............................................",
"user": "{"name":{"firstName":"First_Name","lastName":"Last_Name"},"email":"Email"}"
}
My subsequent respnse body:
{
"state": ".......",
"code": ".............................................."
}
答案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 '@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'],
});
}
}
Response:
{
"code": "..............................................",
"id_token": "..............................................",
"user": "{"name":{"firstName":"First_Name","lastName":"Last_Name"},"email":"Email"}"
}
NB: The user object is only returned on the first login; the subsiquent login returns code and id_token only.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论