Passport.js、Express 和 TypeScript 的 Facebook 身份验证策略
Facebook authentication strategy with Passport.js, Express and TypeScript
我正在尝试使用 Passport.js、Express 和 TypeScript 在我的应用程序上设置 Facebook 身份验证策略。感谢 this article from Hacker Noon,我可以理解流程的数据流。
但是到了验证回调函数的时候,就有点麻烦了。我需要检查用户是否已经登录,因此需要访问 Request 对象。我已经检查了 passport-facebook
模块文档,可以在策略选项上设置 passReqToCallback: true
来启用它。
然而,当我将 req
参数传递给回调函数时,编译器会抛出以下错误:
Argument of type '(req: Request, accessToken: string, _refreshToken: string, profile: Profile, done: any) => void' is not assignable to parameter of type 'VerifyFunction'.
查看 Passport.js 模块的类型定义,我发现了这个:
export type VerifyFunction =
(accessToken: string, refreshToken: string, profile: Profile, done: (error: any, user?: any, info?: any) => void) => void;
export type VerifyFunctionWithRequest =
(req: express.Request, accessToken: string, refreshToken: string, profile: Profile, done: (error: any, user?: any, info?: any) => void) => void;
export class Strategy implements passport.Strategy {
constructor(options: StrategyOptionWithRequest, verify: VerifyFunctionWithRequest);
constructor(options: StrategyOption, verify: VerifyFunction);
name: string;
authenticate(req: express.Request, options?: object): void;
}
因此,理论上,声明
new Strategy(fbConfig, (req: Request, accessToken: string, _refreshToken: string, profile: Profile, done: any) => { ... });
应该可以毫无问题地接受。
这是完整的 fbConfig
声明:
const fbConfig = {
clientID: "",
clientSecret: "",
callbackURL: "",
passReqToCallback: true,
profileFields: [
"id",
"name",
"birhday",
"gender",
"email",
"location",
"hometown"
]
};
还有我的tsconfig.json
:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"strict": true,
"noImplicitAny": true,
"esModuleInterop": true,
"baseUrl": ".",
"outDir": "dist",
"paths": {
"@models/*": ["./src/models/*"],
"@configs/*": ["./src/configs/*"],
"@controllers/*": ["./src/controllers/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
如果有人能帮我解决这个问题,我将不胜感激!
Typescript 实际上有一个带有 Facebook OAuth 完全设置的 NodeJS 初学者工具包,所以人们可以在这里观察它是如何实现的:
https://github.com/microsoft/TypeScript-Node-Starter
你可以在这里找到他们使用 Facebook 实现的护照:
https://github.com/microsoft/TypeScript-Node-Starter/blob/master/src/config/passport.ts
看起来他们正在将 "Request" 转换为 any
我怀疑这是因为 express/passport/Typescript 标准库之间 Request
的定义存在冲突,但无法确定
我已经尝试了 Shanon Jackson 推荐的方法,但没有用。编译器无法识别 Strategy
class.
的重载构造函数
所以我所做的是:
new Strategy(
fbConfig as StrategyOptionWithRequest,
(
req: Request,
accessToken: string,
_refreshToken: string,
profile: Profile,
done
) => { ... }
);
我想将 fbConfig
对象强制转换为 StrategyOptionWithRequest
会强制编译器使用需要该接口的构造函数。然后我注解了回调函数参数的类型,但是把done
留给了编译推理系统去处理。将它注释为 any
似乎与 VSCode 的 IntelliSense 系统有点混乱,使其不显示 done
的预期参数。
我正在尝试使用 Passport.js、Express 和 TypeScript 在我的应用程序上设置 Facebook 身份验证策略。感谢 this article from Hacker Noon,我可以理解流程的数据流。
但是到了验证回调函数的时候,就有点麻烦了。我需要检查用户是否已经登录,因此需要访问 Request 对象。我已经检查了 passport-facebook
模块文档,可以在策略选项上设置 passReqToCallback: true
来启用它。
然而,当我将 req
参数传递给回调函数时,编译器会抛出以下错误:
Argument of type '(req: Request, accessToken: string, _refreshToken: string, profile: Profile, done: any) => void' is not assignable to parameter of type 'VerifyFunction'.
查看 Passport.js 模块的类型定义,我发现了这个:
export type VerifyFunction =
(accessToken: string, refreshToken: string, profile: Profile, done: (error: any, user?: any, info?: any) => void) => void;
export type VerifyFunctionWithRequest =
(req: express.Request, accessToken: string, refreshToken: string, profile: Profile, done: (error: any, user?: any, info?: any) => void) => void;
export class Strategy implements passport.Strategy {
constructor(options: StrategyOptionWithRequest, verify: VerifyFunctionWithRequest);
constructor(options: StrategyOption, verify: VerifyFunction);
name: string;
authenticate(req: express.Request, options?: object): void;
}
因此,理论上,声明
new Strategy(fbConfig, (req: Request, accessToken: string, _refreshToken: string, profile: Profile, done: any) => { ... });
应该可以毫无问题地接受。
这是完整的 fbConfig
声明:
const fbConfig = {
clientID: "",
clientSecret: "",
callbackURL: "",
passReqToCallback: true,
profileFields: [
"id",
"name",
"birhday",
"gender",
"email",
"location",
"hometown"
]
};
还有我的tsconfig.json
:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"strict": true,
"noImplicitAny": true,
"esModuleInterop": true,
"baseUrl": ".",
"outDir": "dist",
"paths": {
"@models/*": ["./src/models/*"],
"@configs/*": ["./src/configs/*"],
"@controllers/*": ["./src/controllers/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
如果有人能帮我解决这个问题,我将不胜感激!
Typescript 实际上有一个带有 Facebook OAuth 完全设置的 NodeJS 初学者工具包,所以人们可以在这里观察它是如何实现的:
https://github.com/microsoft/TypeScript-Node-Starter 你可以在这里找到他们使用 Facebook 实现的护照: https://github.com/microsoft/TypeScript-Node-Starter/blob/master/src/config/passport.ts
看起来他们正在将 "Request" 转换为 any
我怀疑这是因为 express/passport/Typescript 标准库之间 Request
的定义存在冲突,但无法确定
我已经尝试了 Shanon Jackson 推荐的方法,但没有用。编译器无法识别 Strategy
class.
所以我所做的是:
new Strategy(
fbConfig as StrategyOptionWithRequest,
(
req: Request,
accessToken: string,
_refreshToken: string,
profile: Profile,
done
) => { ... }
);
我想将 fbConfig
对象强制转换为 StrategyOptionWithRequest
会强制编译器使用需要该接口的构造函数。然后我注解了回调函数参数的类型,但是把done
留给了编译推理系统去处理。将它注释为 any
似乎与 VSCode 的 IntelliSense 系统有点混乱,使其不显示 done
的预期参数。