docs: function csurf (options) {
    var opts = options || {}
  
    // get cookie options
    var cookie = getCookieOptions(opts.cookie)
  
    // get session options
    var sessionKey = opts.sessionKey || 'session'
  
    // get value getter
    var value = opts.value || defaultValue
  
    // token repo
    var tokens = new Tokens(opts)
  
    // ignored methods
    var ignoreMethods = opts.ignoreMethods === undefined
      ? ['GET', 'HEAD', 'OPTIONS']
      : opts.ignoreMethods
  
    if (!Array.isArray(ignoreMethods)) {
      throw new TypeError('option ignoreMethods must be an array')
    }
  
    // generate lookup
    var ignoreMethod = getIgnoredMethods(ignoreMethods)
  
    return function csrf (req, res, next) {
      // validate the configuration against request
      if (!verifyConfiguration(req, sessionKey, cookie)) {
        return next(new Error('misconfigured csrf'))
      }
  
      // get the secret from the request
      var secret = getSecret(req, sessionKey, cookie)
      var token
  
      // lazy-load token getter
      req.csrfToken = function csrfToken () {
        var sec = !cookie
          ? getSecret(req, sessionKey, cookie)
          : secret
  
        // use cached token if secret has not changed
        if (token && sec === secret) {
          return token
        }
  
        // generate & set new secret
        if (sec === undefined) {
          sec = tokens.secretSync()
          setSecret(req, res, sessionKey, sec, cookie)
        }
  
        // update changed secret
        secret = sec
  
        // create new token
        token = tokens.create(secret)
  
        return token
      }
  
      // generate & set secret
      if (!secret) {
        secret = tokens.secretSync()
        setSecret(req, res, sessionKey, secret, cookie)
      }
  
      // verify the incoming token
      if (!ignoreMethod[req.method] && !tokens.verify(secret, value(req))) {
        return next(createError(403, 'invalid csrf token', {
          code: 'EBADCSRFTOKEN'
        }))
      }
  
      next()
    }
  }