在thinkjs框架中,如何判斷請求是否爲https協議請求

在thinkjs框架中,如何判斷請求是否爲https協議請求

首先,咱們要明白一個點,在Think-js 官方文檔 2.2 - http模塊中,官方闡述了html

http.req , http.res是系統原生的request,response對象!node

從整篇api文檔來看,http模塊並無實現相似express的 req.protocol,req.secure的內容。所以咱們沒法從請求上直接獲取該請求是http仍是https。express

怎麼辦?

瞭解如何獲取協議類型,咱們須要先有一些內容須要api

https是什麼?

HTTPS (also called HTTP over TLS, HTTP over SSL,and HTTP Secure]) is a protocol for secure communication over a computer network which is widely used on the Internet.安全


簡而言之https就是創建在安全套接層(ssl)或安全傳輸層協議(tls)上的安全通訊協議,被普遍應用於英特網。不過目前來講,咱們真正普遍使用的是TLS協議app

若是使用TLS,咱們該怎麼判斷

當使用TLS的時候 net.Socket會收到一個值爲byte 22的頭數據,該數據代表了握手時使用了TLS協議框架

var net = require('net');
var baseAddress = 3000;
net.createServer(tcpConnection).listen(baseAddress);
function tcpConnection(conn) {
    conn.once('data', function (buf) {
        var address = (buf[0] === 22) ? console.log('https') : console.log('http');
        });
    });
}

顯然這個不適合咱們,由於咱們目前須要的是在控制器裏獲取到protocol類型。koa


另外一種判斷方法socket

若是咱們願意翻看koa或者express的源碼,咱們能夠很輕易的獲取到咱們想要的知識tcp

如下是express對protocol的處理

/**
 * Return the protocol string "http" or "https"
 * when requested with TLS. When the "trust proxy"
 * setting trusts the socket address, the
 * "X-Forwarded-Proto" header field will be trusted
 * and used if present.
 *
 * If you're running behind a reverse proxy that
 * supplies https for you this may be enabled.
 *
 * @return {String}
 * @public
 */

defineGetter(req, 'protocol', function protocol(){
  var proto = this.connection.encrypted
    ? 'https'
    : 'http';
  var trust = this.app.get('trust proxy fn');

  if (!trust(this.connection.remoteAddress, 0)) {
    return proto;
  }

  // Note: X-Forwarded-Proto is normally only ever a
  //       single value, but this is to be safe.
  proto = this.get('X-Forwarded-Proto') || proto;
  return proto.split(/\s*,\s*/)[0];
});

/**
 * Short-hand for:
 *
 *    req.protocol === 'https'
 *
 * @return {Boolean}
 * @public
 */

defineGetter(req, 'secure', function secure(){
  return this.protocol === 'https';
});

從代碼中咱們能夠看出,node在使用TLS的時候,會在原生的connection對象上攜帶加密信息,若是非TLS,這個request.connection.encrypted將會是undefined。若是express設置了信任代理,會先檢測設置的信任代理的地址是否與遠端地址相符,或者頭信息中攜帶'X-Forwarded-Proto'(多是來自於Nginx或其餘代理時加上的協議指示),也會返回相應protocol類型。


在thinkjs中,沒有相似express app.set('trust proxy')的方法,因此咱們直接在控制器裏這樣寫就好了

// controller xxx.js

'use strict';

import Base from './base.js';

function getProtocol(http) {
    let proto = http.req.connection.encrypted ? 'https' : 'http';
    proto = http. header('X-Forwarded-Proto') || proto;
    return proto.split(/\s*,\s*/)[0];
}

export default class extends Base {
  /**
   * index action
   * @return {Promise} []
   */
  * indexAction(){

    console.log('protocol:', getProtocol(this.http))

  }
}

整合獲取protocol功能略。

相關文章
相關標籤/搜索