zoukankan      html  css  js  c++  java
  • koa2cors实现过程以及应用

    1、下面以koa2为例

    var koa = require('koa');
    var app = new koa();
    var router = require('koa-router')();
    // CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
    // 下面以koa2-cors为例,
    const cors = require('koa2-cors');
    
    // 具体参数我们在后面进行解释
    app.use(cors({
        origin: function (ctx) {
            if (ctx.url === '/test') {
                return "*"; // 允许来自所有域名请求
            }
            return 'http://localhost:8080'; / 这样就能只允许 http://localhost:8080 这个域名的请求了
        },
        exposeHeaders: ['WWW-Authenticate', 'Server-Authorization'],
        maxAge: 5,
        credentials: true,
        allowMethods: ['GET', 'POST', 'DELETE'],
        allowHeaders: ['Content-Type', 'Authorization', 'Accept'],
    }))
    
    router.post('/', async function (ctx) {
        ctx.body = '恭喜 __小简__ 你成功登陆了'
    });
    
    app
        .use(router.routes())
        .use(router.allowedMethods());
    
    app.listen(3000);
    

      

    2、下面我们在http://localhost:8080发送请求进行测试

    this.$axios.post('http://172.16.186.50:3000/', {})
                        .then((response) => {
                            console.log(response)
                        })
                        .catch(function (error) {
                            console.log(error);
                        });
    

      

     
     

    3、下面我们以具体的请求头信息解释上面的代码,也就是cors具体的实现过程

    // 我们可以用下面的中间件理解app.use(cors({}))
    app.use(async (ctx, next) => {
        // 允许来自所有域名请求
        ctx.set("Access-Control-Allow-Origin", "*");
        // 这样就能只允许 http://localhost:8080 这个域名的请求了
        // ctx.set("Access-Control-Allow-Origin", "http://localhost:8080"); 
    
        // 设置所允许的HTTP请求方法
        ctx.set("Access-Control-Allow-Methods", "OPTIONS, GET, PUT, POST, DELETE");
    
        // 字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段.
        ctx.set("Access-Control-Allow-Headers", "x-requested-with, accept, origin, content-type");
    
        // 服务器收到请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。
    
        // Content-Type表示具体请求中的媒体类型信息
        ctx.set("Content-Type", "application/json;charset=utf-8");
    
        // 该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。
        // 当设置成允许请求携带cookie时,需要保证"Access-Control-Allow-Origin"是服务器有的域名,而不能是"*";
        ctx.set("Access-Control-Allow-Credentials", true);
    
        // 该字段可选,用来指定本次预检请求的有效期,单位为秒。
        // 当请求方法是PUT或DELETE等特殊方法或者Content-Type字段的类型是application/json时,服务器会提前发送一次请求进行验证
        // 下面的的设置只本次验证的有效时间,即在该时间段内服务端可以不用进行验证
        ctx.set("Access-Control-Max-Age", 300);
    
        /*
        CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:
            Cache-Control、
            Content-Language、
            Content-Type、
            Expires、
            Last-Modified、
            Pragma。
        */
        // 需要获取其他字段时,使用Access-Control-Expose-Headers,
        // getResponseHeader('myData')可以返回我们所需的值
        ctx.set("Access-Control-Expose-Headers", "myData");
    
        await next();
    })
    

      

     源码:

    /**
     * CORS middleware for koa2
     *
     * @param {Object} [options]
     *  - {String|Function(ctx)} origin `Access-Control-Allow-Origin`, default is request Origin header
     *  - {Array} exposeHeaders `Access-Control-Expose-Headers`
     *  - {String|Number} maxAge `Access-Control-Max-Age` in seconds
     *  - {Boolean} credentials `Access-Control-Allow-Credentials`
     *  - {Array} allowMethods `Access-Control-Allow-Methods`,
     *    default is ['GET', 'PUT', 'POST', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']
     *  - {Array} allowHeaders `Access-Control-Allow-Headers`
     * @return {Function}
     * @api public
     */
    module.exports = function crossOrigin(options = {}) {
      const defaultOptions = {
        allowMethods: ['GET', 'PUT', 'POST', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'],
      };
    
      // set defaultOptions to options
      options = Object.assign({}, defaultOptions, options); // eslint-disable-line no-param-reassign
    
      // eslint-disable-next-line consistent-return
      return async function cors(ctx, next) {
        // always set vary Origin Header
        // https://github.com/rs/cors/issues/10
        ctx.vary('Origin');
    
        let origin;
        if (typeof options.origin === 'function') {
          origin = options.origin(ctx);
        } else {
          origin = options.origin || ctx.get('Origin') || '*';
        }
        if (!origin) {
          return await next();
        }
    
        // Access-Control-Allow-Origin
        ctx.set('Access-Control-Allow-Origin', origin);
    
        if (ctx.method === 'OPTIONS') {
          // Preflight Request
          if (!ctx.get('Access-Control-Request-Method')) {
            return await next();
          }
    
          // Access-Control-Max-Age
          if (options.maxAge) {
            ctx.set('Access-Control-Max-Age', String(options.maxAge));
          }
    
          // Access-Control-Allow-Credentials
          if (options.credentials === true) {
            // When used as part of a response to a preflight request,
            // this indicates whether or not the actual request can be made using credentials.
            ctx.set('Access-Control-Allow-Credentials', 'true');
          }
    
          // Access-Control-Allow-Methods
          if (options.allowMethods) {
            ctx.set('Access-Control-Allow-Methods', options.allowMethods.join(','));
          }
    
          // Access-Control-Allow-Headers
          if (options.allowHeaders) {
            ctx.set('Access-Control-Allow-Headers', options.allowHeaders.join(','));
          } else {
            ctx.set('Access-Control-Allow-Headers', ctx.get('Access-Control-Request-Headers'));
          }
    
          ctx.status = 204; // No Content
        } else {
          // Request
          // Access-Control-Allow-Credentials
          if (options.credentials === true) {
            if (origin === '*') {
              // `credentials` can't be true when the `origin` is set to `*`
              ctx.remove('Access-Control-Allow-Credentials');
            } else {
              ctx.set('Access-Control-Allow-Credentials', 'true');
            }
          }
    
          // Access-Control-Expose-Headers
          if (options.exposeHeaders) {
            ctx.set('Access-Control-Expose-Headers', options.exposeHeaders.join(','));
          }
    
          try {
            await next();
          } catch (err) {
            throw err;
          }
        }
      };
    };
    

      

    参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Request-Headers


  • 相关阅读:
    跨媒体安全
    kali视频(21-25)学习
    kali视频(26-30)学习
    kali视频(16-20)学习
    kali视频学习(11-15)
    kali视频(1-5)
    使用Metaspoit攻击MS08-067
    web应用程序安全攻防---sql注入和xss跨站脚本攻击
    -区块链-
    TCP/IP网络协议攻击
  • 原文地址:https://www.cnblogs.com/ygunoil/p/15701571.html
Copyright © 2011-2022 走看看