【问题标题】:Facebook authentication strategy with Passport.js, Express and TypeScript使用 Passport.js、Express 和 TypeScript 的 Facebook 身份验证策略
【发布时间】:2019-11-09 22:07:12
【问题描述】:

我正在尝试使用 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"]
}

如果有人能帮我解决这个问题,我将不胜感激!

【问题讨论】:

  • 只是为了删除明显的,确保您从“express”导入 { Request },而不是使用 Typescript 的标准库类型定义 Request
  • 哦,是的。我肯定会这样做。我以前为这个错误受过很多苦。

标签: node.js typescript express passport.js passport-facebook


【解决方案1】:

我尝试了Shanon Jackson 推荐的方法,但没有奏效。编译器无法识别 Strategy 类的重载构造函数。

所以我做的是:

new Strategy(
  fbConfig as StrategyOptionWithRequest, 
  (
    req: Request,
    accessToken: string,
    _refreshToken: string,
    profile: Profile,
    done
  ) => { ... }
);

我想将fbConfig 对象转换为StrategyOptionWithRequest 会强制编译器使用预期该接口的构造函数。然后我注释了回调函数参数的类型,但是把done留给了编译推理系统来处理。将其注释到 any 似乎与 VSCode 的 IntelliSense 系统有点混淆,使其不显示 done 的预期参数。

【讨论】:

    【解决方案2】:

    Typescript 实际上有一个 NodeJS 入门工具包和 Facebook OAuth 完全设置,因此人们可以在这里观察它是如何实现的:

    https://github.com/microsoft/TypeScript-Node-Starter 你可以在这里找到他们使用 Facebook 实施的护照: https://github.com/microsoft/TypeScript-Node-Starter/blob/master/src/config/passport.ts

    看起来他们正在将“请求”投射到 any 我怀疑这是因为 express/passport/Typescript 标准库之间的 Request 定义冲突,但不能确定

    【讨论】:

    • 感谢您的回答。他们投射请求对象的方式对我来说有点奇怪,但我会尝试一下。希望它有效。
    • 所以,它没有工作,尽管提到的启动项目没有任何缺陷。但我可以找到解决办法。我会发布一个答案。
    猜你喜欢
    • 2015-11-01
    • 2015-04-08
    • 2014-12-16
    • 2020-07-20
    • 1970-01-01
    • 2018-10-21
    • 2015-01-09
    • 1970-01-01
    • 2020-07-03
    相关资源
    最近更新 更多