分享一个实用Nodejs npm包:koa-csrf


当前第2页 返回上一页

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

const csrf = require('csrf');

 

class CSRF {

  constructor(opts = {}) {

    // opts配置对象、并且有提供默认配置

    // 允许自定义配置对象进行覆盖

    this.opts = Object.assign(

      {

        // 使 koa 抛出的错误信息内容,默认值为:'Invalid CSRF token'。

        // 它可以是一个接收 ctx 作为参数的函数,函数最后返回错误信息内容。

        invalidTokenMessage: 'Invalid CSRF token',

        // 验证失败时的响应状态码,默认值为:403(Forbidden)

        // 跟 invalidTokenMessage 参数一样,它也会被传递给 ctx.throw,用于抛出错误和拒绝请求。

        invalidTokenStatusCode: 403,

        // 排除的请求方法,默认值为:['GET', 'HEAD', 'OPTIONS']。

        excludedMethods: ['GET', 'HEAD', 'OPTIONS'],

        // 是否禁止通过查询字符串传递 _csrf 校验 token,默认值为 false

        // 如果校验 token 出现在 URL 中,则可能会通过 Referer 泄露,应尽量把 Token 放在表单中,把敏感操作由 GET 改为 POST。

        disableQuery: false

      },

      opts

    );

 

    // 生成token generation/verification instance

    this.tokens = csrf(opts);

    // 早期很多这样的中间件写法、对接koa中间件

    return this.middleware.bind(this);

  }

 

  // koa中间件

  middleware(ctx, next) {

    // __defineGetter__ API已经不推荐使用

    // 在ctx上挂载csrf属性。

    // 当读取ctx.csrf会执行该回调

    ctx.__defineGetter__('csrf', () => {

      // 如果已经存在直接返回、避免多次生成

      if (ctx._csrf) {

        return ctx._csrf;

      }

      // csrf依赖于koa session

      if (!ctx.session) {

        return null;

      }

 

      // 生成一个secret存储在ctx.session.secret

      if (!ctx.session.secret) {

        ctx.session.secret = this.tokens.secretSync();

      }

      // 根据上述的secret生成csrf toke存到ctx._csrf

      // 一般非框架本身属性,都建议_xx表示私有

      ctx._csrf = this.tokens.create(ctx.session.secret);

      // 返回

      return ctx._csrf;

    });

 

    // 挂栽ctx.response.csrf属性

    ctx.response.__defineGetter__('csrf', () => ctx.csrf);

 

    // 如果是请求方法黑名单直接不处理

    if (this.opts.excludedMethods.indexOf(ctx.method) !== -1) {

      return next();

    }

 

    if (!ctx.session.secret) {

      ctx.session.secret = this.tokens.secretSync();

    }

 

    // 从ctx.request.body取出客户端传递过来的_csrf token

    // 因此依赖于koa-bodyparser类库

    const bodyToken =

      ctx.request.body && typeof ctx.request.body._csrf === 'string'

        ? ctx.request.body._csrf

        : false;

 

    // 除了从body获取token

    // 支持从ctx.query._csrf即get方法查询字符串

    // 支持从请求头获取 'csrf-token'、'xsrf-token'、'x-csrf-token'、'x-xsrf-token'

    const token =

      bodyToken ||

      (!this.opts.disableQuery && ctx.query && ctx.query._csrf) ||

      ctx.get('csrf-token') ||

      ctx.get('xsrf-token') ||

      ctx.get('x-csrf-token') ||

      ctx.get('x-xsrf-token');

 

      // 如果获取失败、根据配置对象的信息、抛出异常

    if (!token) {

      return ctx.throw(

        this.opts.invalidTokenStatusCode,

        typeof this.opts.invalidTokenMessage === 'function'

          ? this.opts.invalidTokenMessage(ctx)

          : this.opts.invalidTokenMessage

      );

    }

 

    // 校验token失败

    if (!this.tokens.verify(ctx.session.secret, token)) {

      return ctx.throw(

        this.opts.invalidTokenStatusCode,

        typeof this.opts.invalidTokenMessage === 'function'

          ? this.opts.invalidTokenMessage(ctx)

          : this.opts.invalidTokenMessage

      );

    }

    // 校验成功

    return next();

  }

}

 

module.exports = CSRF;

下一期我们看下csrf库,这个里面处理更多相关逻辑。

好了,今天就到这结束了,下期见。

ps:如果你对node也有兴趣,欢迎关注我公众号:xyz编程日记。

相关推荐:《nodejs 教程》

以上就是分享一个实用Nodejs npm包:koa-csrf的详细内容,更多文章请关注木庄网络博客

返回前面的内容

相关阅读 >>

node.js中如何创建和提取zip文件?方法介绍

一文搞懂node.js中的事件循环

了解nodejs中的事件和事件循环

了解node.js中的process对象

node.js如何使用文件系统模块?常用fs模块方法介绍

node.js+koa搭建一个简单后台管理系统

如何在macos上安装node.js和npm

深入研究node.js中的日志信息

node.js是什么?优势是什么?

linux服务器搭建node.js环境的步骤介绍

更多相关阅读请进入《node.js》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...