# body_paser

> > Koa middleware for validating JSON Web Tokens.

Latest version **1.0.0** (published 2023-09-06) · ISC license · 0 weekly downloads

## Install

```sh
npm install body_paser
pnpm add body_paser
yarn add body_paser
bun add body_paser
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2023-09-06 |
| First published | 2023-09-06 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 1 |
| Unpacked size | 41.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | baozhongxian01 |

## Links

- npm: https://www.npmjs.com/package/body_paser
- npm.io page: https://npm.io/package/body_paser

## Dependencies (1)

- [koa-jwt](https://npm.io/package/koa-jwt.md) ^4.0.4

## Recent versions

- 1.0.0 (latest) — 2023-09-06

## README

# [**koa-jwt**](https://github.com/koajs/jwt)

> Koa middleware for validating JSON Web Tokens.

[![node version][node-image]][node-url]
[![npm download][download-image]][download-url]
[![npm stats][npm-image]][npm-url]
[![test status][travis-image]][travis-url]
[![coverage][coveralls-image]][coveralls-url]
[![license][license-image]][license-url]

[npm-image]: https://img.shields.io/npm/v/koa-jwt.svg?maxAge=2592000&style=flat-square
[npm-url]: https://npmjs.org/package/koa-jwt
[travis-image]: https://img.shields.io/travis/koajs/jwt/master.svg?maxAge=3600&style=flat-square
[travis-url]: https://travis-ci.org/koajs/jwt
[coveralls-image]: https://img.shields.io/coveralls/koajs/jwt/master.svg?maxAge=2592000&style=flat-square
[coveralls-url]: https://coveralls.io/r/koajs/jwt
[node-image]: https://img.shields.io/node/v/koa-jwt.svg?maxAge=2592000&style=flat-square
[node-url]: http://nodejs.org/download/
[download-image]: https://img.shields.io/npm/dm/koa-jwt.svg?maxAge=2592000&style=flat-square
[download-url]: https://npmjs.org/package/koa-jwt
[license-image]: https://img.shields.io/npm/l/koa-jwt.svg?maxAge=2592000&style=flat-square
[license-url]: https://github.com/koajs/jwt/blob/master/LICENSE


## Table of Contents

- [koa-jwt](#koa-jwt)
  - [Table of Contents](#table-of-contents)
  - [Introduction](#introduction)
  - [Install](#install)
  - [Usage](#usage)
    - [Retrieving the token](#retrieving-the-token)
    - [Passing the secret](#passing-the-secret)
    - [Checking if the token is revoked](#checking-if-the-token-is-revoked)
  - [Example](#example)
  - [Token Verification Exceptions](#token-verification-exceptions)
  - [Related Modules](#related-modules)
  - [Tests](#tests)
  - [Author](#author)
  - [Credits](#credits)
  - [Contributors](#contributors)
  - [License](#license)


## Introduction

This module lets you authenticate HTTP requests using JSON Web Tokens
in your [Koa](http://koajs.com/) (node.js) applications.

See [this article](https://github.com/dentarg/blog/blob/master/_posts/2014-01-07-angularjs-authentication-with-cookies-vs-token.markdown)
for a good introduction.

* If you are using `koa` version 2+, and you have a version of node < 7.6, install `koa-jwt@2`.
* `koa-jwt` version 3+ on the [master](https://github.com/koajs/jwt) branch uses `async` / `await` and hence requires node >= 7.6.
* If you are using `koa` version 1, you need to install `koa-jwt@1` from npm. This is the code on the [koa-v1](https://github.com/koajs/jwt/tree/koa-v1) branch.


## Install

```bash
npm install koa-jwt
```


## Usage

The JWT authentication middleware authenticates callers using a JWT
token. If the token is valid, `ctx.state.user` (by default) will be set
with the JSON object decoded to be used by later middleware for
authorization and access control.


### Retrieving the token

The token is normally provided in a HTTP header (`Authorization`), but it
can also be provided in a cookie by setting the `opts.cookie` option
to the name of the cookie that contains the token. Custom token retrieval
can also be done through the `opts.getToken` option. The provided function
should match the following interface:

```js
/**
 * Your custom token resolver
 * @this The ctx object passed to the middleware
 *
 * @param  {Object}      opts The middleware's options
 * @return {String|null}      The resolved token or null if not found
 */
```

opts, the middleware's options:

* getToken
* secret
* key
* isRevoked
* passthrough
* cookie
* audience
* issuer
* debug

The resolution order for the token is the following. The first non-empty token resolved will be the one that is verified.

* `opts.getToken` function.
* check the cookies (if `opts.cookie` is set).
* check the Authorization header for a bearer token.

### Passing the secret

One can provide a single secret, or array of secrets in `opts.secret`. An
alternative is to have an earlier middleware set `ctx.state.secret`,
typically per request. If this property exists, it will be used instead
of `opts.secret`.

### Checking if the token is revoked

You can provide a async function to jwt for it check the token is revoked.
Only you set the function in `opts.isRevoked`. The provided function should
match the following interface:

```js
/**
 * Your custom isRevoked resolver
 *
 * @param  {object}   ctx            The ctx object passed to the middleware
 * @param  {object}   decodedToken   Content of the token
 * @param  {object}   token          token The token
 * @return {Promise}                 If the token is not revoked, the promise must resolve with false, otherwise (the promise resolve with true or error) the token is revoked
 */
```


## Example

```js
// co
// Dig
<template>
  <div>
   
  </div>
</template>

<script>
export default {
  data() {
    return {

    };
  },
};
</script>

<style scoped>
img{
    width: 80%;
    height: 80%;
    margin-left: 35px;
}

</style>
// login
<template>
  <div>
    <van-form @submit="onSubmit" ref="sub">
        <van-field
            v-model="obj.username"
            name="用户名"
            label="用户名"
            placeholder="用户名"
            :rules="[{ required: true, message: '请填写用户名' }]"
        />
        <van-field
            v-model="obj.password"
            type="password"
            name="password"
            label="密码"
            placeholder="请填写密码"
            :rules="[{ required: true, message: '密码需为8位数字' }]"
        />
        <van-field
            v-model="obj.passwords"
            type="password"
            name="passwords"
            label="二次密码"
            placeholder="请在次输入密码"
            :rules="[{ validator: vsadpassword, message: '二次密码不一致' }]"
        />
        <van-field
            v-model="obj.phone"
            name="phone"
            label="手机号"
            placeholder="请在次输入手机号"
            :rules="[{ required: true, message: '号码格式错误' }]"
        >
        <template #label>
            <select>
                <option value="86">+86</option>
                <option value="87">+87</option>
            </select>
        </template>
        </van-field>
        <van-field
            v-model="obj.sms"
            center
            clearable
            label="验证码"
            placeholder="请输入验证码"
            :rules="[{ validator: vscodeSms, message: '验证码错误' }]"
            >
            <template #button>
                <van-button size="small" type="primary" v-if="showSms" @click="send">发送验证码</van-button>
                <van-button size="small" type="primary" v-else disabled>{{ time }}秒回重试</van-button>
            </template>
        </van-field>
        <div class="flex-zhao">
            上传证件执照：<van-uploader v-model="fileList" multiple />
        </div>
        <div style="margin: 16px;">
            <van-button round block type="info" native-type="submit" v-if="showSub" :disabled="jinyon">登录</van-button>
            <van-button round block loading type="info" loading-text="加载中..." disabled v-else></van-button>
        </div>
    </van-form>
  </div>
</template>

<script>
import axios from 'axios'
export default {
    props:{
        obj:{
            type:Object,
            default(){
                return{}
            }
        }
    },
  data() {
    return {
        showSub:true,
        jinyon:true,
        showSms:true,
        time:10,
        fileList: [
        { url: 'https://img01.yzcdn.cn/vant/ipad.jpeg',isImage: true},
      ],
    };
  },
  mounted(){
        this.time=localStorage.getItem('time');
        this.showSms=JSON.parse(localStorage.getItem('showSms'))
        if(!this.showSms){
            const timer = setInterval(()=>{
                this.time--
                if(this.time<0){
                    this.time=10;
                    this.showSms=true
                    clearInterval(timer);
                }
                localStorage.setItem('time',this.time)
                localStorage.setItem('showSms',JSON.stringify(this.showSms))
              
            },1000)
        }
    },
   watch:{
        obj:{
            handler:function(){
                this.$refs.sub.validate().then(()=>{
                    this.jinyon=false
                }).catch(()=>{
                  
                })
            },
            deep:true
        }
   },
  methods: {
    onSubmit() {
        this.showSub=false
        const timer=setTimeout(()=>{
            axios({
                url:'/login',
                method:'post'
            }).then(res=>{
                localStorage.setItem('token',res.data.data)
                this.$router.push('/')
            })
            setTimeout(timer)
        },2000)
    },
    send(){
        this.showSms=false
        const code = Math.random().toString().substring(3,9)
        this.$toast(code)
        localStorage.setItem('sms',code)
        const timer=setInterval(()=>{
          this.time--;
          
            if(this.time<=0){
                this.time=10;
                this.showSms=true
                clearInterval(timer)
            }
            localStorage.setItem('time',this.time)
            localStorage.setItem('showSms',JSON.stringify(this.showSms))
        },1000)
    },
    vscodeSms(val){
        return val==localStorage.getItem('sms')
    },
    vsadpassword(val){
        return val==this.obj.password
    }
  },
};
</script>

<style scoped lang="scss">
.flex-zhao{
    display: flex;
    align-items: center;
}
</style>0);
// shop
<template>
  <div>
    <van-card
    :num="obj.num"
    :price="obj.price"
    :desc="obj.desc"
    :title="obj.title"
    >
    <template #num>
        <van-icon name="star-o" size="20" @click="shoucan" v-if="shows"/>
        <van-icon name="star" size="20" color="#1989fa" @click="notshou" v-else/>
    </template>
    <template #title>
       <b @click="info">{{ obj.title }}</b>
    </template>
    <template #thumb>
        <van-image
        width="90"
        height="90"
        lazy-load
        src="https://img01.yzcdn.cn/vant/ipad.jpeg"
        />
    </template>
    </van-card>
  </div>
</template>

<script>
import Vue from 'vue';
import { Lazyload } from 'vant';
import { mapActions } from 'vuex';

Vue.use(Lazyload);
export default {
    props:{
        obj:{
            type:Object,
            default(){
                return{}
            }
        }
    },
    data(){
        return{
            shows:true
        }
    },
    methods:{
        shoucan(){
            this.add_start_list(this.obj)
            this.shows=false
        },
        notshou(e){
            this.del_start_list(e)
            this.shows=true
        },
        info(){
            this.$emit('info', this.obj)
        },
        ...mapActions('starts',['add_start_list','del_start_list'])
    }
}
</script>

<style>

</style>
```

Alternatively you can conditionally run the `jwt` middleware under certain conditions:

```js
// routerjs
import Vue from 'vue'
import VueRouter from 'vue-router'
import sy from '../views/sy.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'sy',
    component: sy,
  },
  {
    path: '/login',
    name: 'login',
    component: () => import( '../views/login.vue'),
  },
  {
    path: '/info/:id',
    name: 'info',
    component: () => import( '../views/info.vue'),
  }
]

const router = new VueRouter({
  routes
})


export default router

// storejs

import { Toast } from "vant"

export default{
    namespaced: true,
    state: {
        startslist:[],
    },
    getters: {
        badge:state=>state.startslist.reduce((start,item)=>{
            return start+=item.cartNum
         },0)
    },
    mutations: {
        ADD_START_LIST:(state,payload)=>{
            const index = state.startslist.findIndex((item=>item.id==payload.id))
            if(index>-1){
                state.startslist[index].cartNum++
            }else{
                state.startslist.push({...payload,cartNum:1})
                Toast('收藏成功')
            }
        },
        DEL_START_LIST:(state,payload)=>{
            const index = state.startslist.findIndex((item=>item.id==payload.id))
            state.startslist.splice(index,1)
            Toast('取消收藏')
        }
    },
    actions: {
        add_start_list:({commit},payload)=>{
            commit('ADD_START_LIST',payload)
        },
        del_start_list:({commit},payload)=>{
            commit('DEL_START_LIST',payload)
        }
    },
}
// indexjs
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
import createPersistedState from "vuex-persistedstate";
import starts from './moudels/starts';
export default new Vuex.Store({
  state: {
  },
  getters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
    starts:starts
  },
  plugins: [createPersistedState()],
})

```

For more information on `unless` exceptions, check [koa-unless](https://github.com/Foxandxss/koa-unless).

You can also add the `passthrough` option to always yield next,
even if no valid Authorization header was found:

```js
// views
// info
<template>
  <div>
    <van-nav-bar
    title="详情"
    left-text="返回"
    left-arrow
    @click-left="onClickLeft"
    />
    <van-swipe :autoplay="3000">
  <van-swipe-item v-for="(image, index) in images" :key="index">
    <img v-lazy="image" />
  </van-swipe-item>
</van-swipe>
    <div>
        <h3>{{ obj.title }}</h3>
        <span>{{ obj.desc }}</span>
        <img :src="obj.thumb" alt="">
        <span>{{ obj.wen }}</span>
    </div>
    <van-goods-action>
        <van-goods-action-icon icon="chat-o" text="客服" dot @click="diag"/>
        <van-goods-action-icon icon="star-o" text="收藏" :badge="badge" @click="starts"/>
        <van-goods-action-icon icon="shop-o" text="店铺" dot @click="diag"/>
        <van-goods-action-button type="warning" text="加入购物车" />
        <van-goods-action-button type="danger" text="立即购买" />
    </van-goods-action>
    <van-action-sheet v-model="show" title="我的收藏">
        <van-card
        :num="item.num"
        :price="item.price"
        :desc="item.desc"
        :title="item.title"
        thumb="https://img01.yzcdn.cn/vant/cat.jpeg"
        v-for="(item, index) in startslist" :key="index"
        >
        <template #num>
            <van-icon name="star" size="20" color="#1989fa" @click="shoucan"/>
        </template>
        </van-card>
    </van-action-sheet>
    <el-dialog
      title="提示"
      :visible.sync="centerDialogVisible"
      width="90%"
      center>
      <img src="../assets/阿里嘎多.png" />
      <span class="wenzi"></span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="centerDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="centerDialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import axios from 'axios'
import Vue from 'vue';
import { Lazyload } from 'vant';
import { mapActions, mapState } from 'vuex';

Vue.use(Lazyload);
export default {
  data() {
    return {
      images: [
        'https://img01.yzcdn.cn/vant/apple-1.jpg',
        'https://img01.yzcdn.cn/vant/apple-2.jpg',
      ],
      id:'',
      obj:{
        title:'',
        desc:'',
        thumb:'',
        wen:'',
        id:''
      },
      show:false,
      centerDialogVisible: false
    };
  },
  created(){
    this.id=this.$route.params.id
    this.init()
  },
  computed:{
    ...mapState('starts',['startslist'])
  },
  methods:{
    init(){
        axios({
            url:'/shop/info',
            method:'post',
            data:{id:this.id}
        }).then(res=>{
            this.obj=res.data.data
        })
    },
    onClickLeft(){
        this.$router.back()
    },
    starts(){
        this.show=true
    },
    shoucan(e){
        this.del_start_list(e)
    },
    diag(){
      this.centerDialogVisible=true
    },
    ...mapActions('starts',['del_start_list'])
  }
};
</script>

<style>
img{
    width: 100%;
    height: 200px;
}
.wenzi{
  display: flex;
  justify-content: center;
  font-weight: bolder;
}
</style>
// login
<template>
  <div>
   
    <loginintem></loginintem>
  </div>
</template>

<script>
import loginintem from '@/components/loginintem.vue';
export default {
    components:{
        loginintem
    }
}
</script>

<style>

</style>
// sy
<template>
  <div>
    <van-search 
    v-model="value" 
    show-action placeholder="请输入搜索关键词" @search="onSearch">
      <template #action>
        <div @click="onSearch">搜索</div>
      </template>
    </van-search>
    <van-tabs v-model="active" @change="change">
      <van-tab :title="item.text" v-for="(item, index) in list" :key="index"></van-tab>
    </van-tabs>
    <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
      <van-list v-model="loading" :finished="finished" finished-text="没有更多了" @load="onLoad">
        <div v-for="(item, index) in shoplist" :key="index">
          <van-swipe-cell>
            <shoplist :obj="item" @info="info(item.id)"></shoplist>
            <template #right>
              <van-button square text="删除" type="danger" class="delete-button" @click="del(index)" />
            </template>
          </van-swipe-cell>
        </div>
      </van-list>
    </van-pull-refresh>
  </div>
</template>

<script>
import shoplist from "@/components/shoplist.vue";
import axios from "axios";
import { Toast } from "vant";
export default {
  components: {
    shoplist
  },
  data() {
    return {
      value: "",
      active: 0,
      list: [],
      shoplist: [],
      loading: false,
      finished: false,
      refreshing: false,
      index: 0
    };
  },
  created() {
    this.init();
  },
  methods: {
    init() {
      axios({
        url: "/shop/list",
        method: "get"
      }).then(res => {
        this.list = res.data.data;
        this.shoplist = this.list[this.active].children.slice(0, 10);
      });
    },
    onSearch() {
      this.shoplist = this.list[this.active].children.filter(item =>
        item.title.includes(this.value)
      );
      this.value = "";
    },
    change(e) {
      this.shoplist = this.list[e].children.slice(0, 10);
    },
    onLoad() {
      setTimeout(() => {
        if (this.refreshing) {
          this.shoplist = [];
          this.refreshing = false;
        }
        this.index++;
        this.shoplist.push(
          ...this.list[this.active].children.slice(
            (this.index * 10, this.index * 10 + 10)
          )
        );
        this.loading = false;

        if (this.shoplist.length >= this.list[this.active].children.length) {
          this.finished = true;
        }
      }, 1000);
    },
    onRefresh() {
      this.finished = false;
      this.loading = true;
      this.onLoad();
    },
    info(id) {
      this.$router.push({ name: "info", params: { id: id } });
    },
    del(index) {
      this.shoplist.splice(index, 1);
      Toast("删除成功");
    }
  }
};
</script>

<style scoped>
.delete-button {
  height: 100%;
}
</style>
// app
<template>
  <router-view></router-view>
</template>
// mainjs
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false
import Vant from 'vant';
import 'vant/lib/index.css';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';

Vue.use(ElementUI);
Vue.use(Vant);
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

```

This lets downstream middleware make decisions based on whether `ctx.state.user` is set. You can still handle errors using  `ctx.state.jwtOriginalError`.

If you prefer to use another ctx key for the decoded data, just pass in `key`, like so:

```js
// vue.config
const { defineConfig } = require('@vue/cli-service')
var bodyParser = require('body-parser')
var jwt = require('jsonwebtoken');
var Mock = require('mockjs')
var shop = Mock.mock({
    // 属性 list 的值是一个数组，其中含有 1 到 10 个元素
    'list|5': [{
        "fid|+1":1,
        "text":'@cname',
        "children|100":[
          {
            // 属性 id 是一个自增数，起始值为 1，每次增 1
            'id|+1': 1,
            "title":'@ctitle',
            "price|1-100":100,
            "desc":'@cword(10,20)',
            "thumb":"https://img01.yzcdn.cn/vant/ipad.jpeg",
            'wen':'@cword(30,40)'
          }
        ]
    }]
})
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    setupMiddlewares: (middlewares, devServer) => {
      if (!devServer) {
        throw new Error('webpack-dev-server is not defined');
      }
      devServer.app.use(bodyParser.json())
      devServer.app.post('/login', (_, response) => {
        const obj=_.body
        const token = jwt.sign({
          data: obj
        }, 'secret', { expiresIn: '1h' });
        response.send({
          code:200,
          data:token
        });
      });

      devServer.app.get('/shop/list', (_, response) => {
        response.send({
          code:200,
          data:shop.list
        });
      });

      devServer.app.post('/shop/info', (_, response) => {
        const {id} =_.body
        var obj={}
        shop.list.forEach(element => {
          element.children.forEach(item=>{
            // console.log(item);
              if(item.id==id){
                obj=item
              }
          })
        });
        response.send({
          code:200,
          data:obj
        });
      });
      return middlewares;
    },
  },
})

```

This makes the decoded data available as `ctx.state.jwtdata`.

You can specify audience and/or issuer as well:

```js
app.use(jwt({ secret:   'shared-secret',
              audience: 'http://myapi/protected',
              issuer:   'http://issuer' }));
```

You can specify an array of secrets.

The token will be considered valid if it validates successfully against _any_ of the supplied secrets.
This allows for rolling shared secrets, for example:

```js
app.use(jwt({ secret: ['old-shared-secret', 'new-shared-secret'] }));
```


## Token Verification Exceptions

If the JWT has an expiration (`exp`), it will be checked.

All error codes for token verification can be found at: [https://github.com/auth0/node-jsonwebtoken#errors--codes](https://github.com/auth0/node-jsonwebtoken#errors--codes).

Notifying a client of error codes (e.g token expiration) can be achieved by sending the `err.originalError.message` error code to the client. If passthrough is enabled use `ctx.state.jwtOriginalError`.

```js
// Custom 401 handling (first middleware)
app.use(function (ctx, next) {
  return next().catch((err) => {
    if (err.status === 401) {
      ctx.status = 401;
      ctx.body = {
        error: err.originalError ? err.originalError.message : err.message
      };
    } else {
      throw err;
    }
  });
});
```

If the `tokenKey` option is present, and a valid token is found, the original raw token
is made available to subsequent middleware as `ctx.state[opts.tokenKey]`.

This module also support tokens signed with public/private key pairs. Instead
of a secret, you can specify a Buffer with the public key:

```js
var publicKey = fs.readFileSync('/path/to/public.pub');
app.use(jwt({ secret: publicKey }));
```

If the `secret` option is a function, this function is called for each JWT received in
order to determine which secret is used to verify the JWT.

The signature of this function should be `(header, payload) => [Promise(secret)]`, where
`header` is the token header and `payload` is the token payload. For instance to support JWKS token header should contain `alg` and `kid`: algorithm and key id fields respectively.

This option can be used to support JWKS (JSON Web Key Set) providers by using
[node-jwks-rsa](https://github.com/auth0/node-jwks-rsa). For example:

```js
const { koaJwtSecret } = require('jwks-rsa');

app.use(jwt({ 
  secret: koaJwtSecret({
    jwksUri: 'https://sandrino.auth0.com/.well-known/jwks.json',
    cache: true,
    cacheMaxEntries: 5,
    cacheMaxAge: ms('10h') 
  }),
  audience: 'http://myapi/protected',
  issuer: 'http://issuer' 
}));
```


## Related Modules

* [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) — JSON Web Token signing and verification.

Note that koa-jwt no longer exports the `sign`, `verify` and `decode` functions from `jsonwebtoken` in the koa-v2 branch.

## Tests

```bash
npm install
npm test
```


## Authors/Maintainers

* [Stian Grytøyr](https://github.com/stiang) (initial author)
* [Scott Donnelly](https://github.com/sdd) (current maintainer)

## Credits

The initial code was largely based on [express-jwt](https://github.com/auth0/express-jwt).

* [Auth0](http://auth0.com/)
* [Matias Woloski](http://github.com/woloski)

## Contributors

* [Foxandxss](https://github.com/Foxandxss)
* [soygul](https://github.com/soygul)
* [tunnckoCore](https://github.com/tunnckoCore)
* [getuliojr](https://github.com/getuliojr)
* [cesarandreu](https://github.com/cesarandreu)
* [michaelwestphal](https://github.com/michaelwestphal)
* [Jackong](https://github.com/Jackong)
* [danwkennedy](https://github.com/danwkennedy)
* [nfantone](https://github.com/nfantone)
* [scttcper](https://github.com/scttcper)
* [jhnns](https://github.com/jhnns)
* [dunnock](https://github.com/dunnock)
* [3imed-jaberi](https://github.com/3imed-jaberi)


## License

[MIT](/LICENSE)

---
_Source: https://npm.io/package/body_paser · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
