【从简】Express Generator搭建HTTPS前端框架

Express是基于Node.js的前端Web开发框架, 其支持友好的API服务,因此我们可以借助Express来模拟API数据进行开发调试。

安装

  1. 查看Node.js的版本
    node -v
    如果没有安装则先安装 可参考:安装Node.js 的Node安装部分

  2. 创建一个测试工程目录,存放Express项目框架
    npm install express-generator -g
    如果连接不上或速度慢可切回国内
    npm install -g cnpm --registry=https://registry.npm.taobao.org
    再执行
    cnpm install express-generator -g
    如果创建成功会出现目录位置如:

link /usr/local/bin/express@ -> /usr/local/lib/node_modules/express-generator/bin/express

3 接着就cd到你自己的路径 执行生产自己工程的目录
express myApp
后提示警告并选择继续

warning: the default view engine will not be jade in future releases
warning: use --view=jade or --help for additional options
destination is not empty, continue? [y/N] y
之后会有一个列表等待安装

【从简】Express Generator搭建HTTPS前端框架_第1张图片
参考

npm install 来安装上这些内容,工程中会多一个node_modules的文件夹,里面是所有依赖包文件。

4 Express模板中的文件,其中bin文件夹下面的www.js文件是服务的启动文件,其中启动了HTTP的服务,默认端口为3000。routes文件夹下面的文件用于配置api路由,默认有index.js与users.js两个。app.js文件中对api进行了初始化与配置。可以在users.js中添加一个测试api如下:

var express = require('express');
var router = express.Router();

/* 这个是默认生成的. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});
/* 添加一个测试api*/
router.get('/testAPi',function(rep,res,next){
  res.send('{name:jaki,age:24}');
});
module.exports = router;

5 cd到自己工程目录下,通过Node启动Express 执行:node bin/www, 或者也可以通过:DEBUG=myappName npm start 来启动。如果服务启动成功就可以在浏览器输入http://127.0.0.1:3000/users/testAPi 会返回我们send()方法传递的字符串

6 如果要取消
MacOS系统在服务进行中,可以使用control+c来释放端口的监听,如果不小心使用control+z或者关闭了终端,会导致所监听端口的无法释放,下次如果再次启动node服务,会报Port 3000 is already in use的错误,可以使用如下方法来进行所监听端口的释放。首先使用如下命令查看所有监听某个端口的服务,例如3000端口:
sudo lsof -i:3000
会列出当前的进程信息:

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 9184 ucsapp 13u IPv6 0xd256c96f6cc1477d 0t0 TCP *:hbci (LISTEN)

在执行杀死这个监听:sudo kill -9 9184

支持HTTPS

搭建HTTPS服务需要有证书凭证,两种证书我们可以选择,一种是CA机构签发的证书,还有一种是我们自己制作的自签名证书.现在创建自签名证书,这里提供两种方法,测试第二种网页在信任完证书后可以正常访问:

方法一:

1 在Mac电脑上打开钥匙串访问应用,打开其中的证书助理

【从简】Express Generator搭建HTTPS前端框架_第2张图片
1

【从简】Express Generator搭建HTTPS前端框架_第3张图片
2

证书的名字自定义,身份类型选择的是 自签名的根证书,证书类型选择 SSL服务器,之后点击创建即可完成证书的创建。

2 从KeyChain中导出.p12文件并设置密码,那这个.p12文件其实是一个复合文件,其中包装了私钥与证书信息,使用OpenSSL工具可以将其中的信息进行提取,而搭建一个支持HTTPS的服务器是需要两个文件,分别问证书文件和私钥文件,下面我们来从.p12文件中提取这些需要的文件。

3 从p12中提取证书和私钥 分别是导出密钥和证书对应nocerts nokeys,openssl导出过程中可能需要输入密码。

openssl pkcs12 -in yourP12Path.p12 -nocerts -out yourPathOfPrivateKey.pem -nodes
openssl pkcs12 -in yourP12Path.p12 -nokeys -out yourPathOfCert.pem -nodes

方法二:

1. openssl genrsa -des3 -out server.key 2048
2. openssl req -new -key server.key -out server.csr
3. cp /Users/xxx/Desktop/server.key server.key.org       
   openssl rsa -in server.key.org -out serverNew.key 
4. openssl x509 -req -days 365 -in /Users/xxx/Desktop/server.csr -signkey /Users/xxx/Desktop/serverNew.key -out serverFinal.crt 

4 将他们拷贝到你Express项目的bin文件夹下


【从简】Express Generator搭建HTTPS前端框架_第4张图片
1

5 在启动入口处即/bin/www文件里录入一下代码支持HTTPS

/*
HTTPS
*/
var fs = require('fs');
var https = require('https');
/*
密钥文件
*/
var privatekey = fs.readFileSync('bin/privateKey.pem', 'utf8');  
/*
证书文件
*/
var certificate = fs.readFileSync('bin/cert.pem', 'utf8');  
var options={key:privatekey, cert:certificate};  
var serverHttps = https.createServer(options, app);  
/*
绑定端口
*/
serverHttps.listen(8080,function () {
    console.log('Https server listening on port ' + 8080);
}); 

6 node bin/www 启动并浏览器输入https://localhost:8080/users 因为我们改变了监听端口为8080,因为支持了https所以不再是http 接下来浏览器就会提示你是否信任该自签名的证书。就算成功告一段落了。

7 付费从CA机构签发的证书是被默认信任的,则iOS工程无需做任何修改,只需将请求url改成https,像上面这种我们自签名的证书是会被默认拒绝访问,xCode会输出错误提示:NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802),。你可以调用试试看:

-(void)checkThisHttps{
    
    NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://localhost:8080/users"]];
    NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession * session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:[NSOperationQueue mainQueue]];
    [[session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"%@,%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],error);
    }] resume];
}
【从简】Express Generator搭建HTTPS前端框架_第5张图片
1

8 如果改成http 监听3000 后又发现xcode限制了http的访问,但我们可以通过设置NSAppTransportSecurity来绕过,其中NSAllowsArbitraryLoads是否允许所有不安全的请求,比如之一的http请求,默认为NO,因而我们又发现其下有一个NSExceptionDomains,里面有一个NSExceptionAllowsInsecureHTTPLoads,设置是否允许此域名使用自签名的证书进行请求,默认为NO,如果设置为YES,则在提交时需要说明原因。最好服务器都换成HTTPS协议的其实CA购买的那种证书免去信任验证问题,不然只能适配验证自签名的HTTPS证书了。

9 在进行HTTPS请求时,服务器会将证书文件返回给客户端,如果客户端的证书信任列表中有这个证书,则此请求可以正常进行,否则请求会被拒。因此,因此我们只需要将自签名的证书安装进客户端的信任列表就可以了。iOS中需要使用的证书是der格式,所以我们将pem格式的证书转换成der格式的证书:

openssl x509 -inform PEM -in cert.pem -outform DER -out cert.der

然后将cert.der导入到iOS工程中,并设置NSURLSession的delegate为self后在回调用设置这个服务器中的证书文件对应的der证书为可信任就行了。自此HTTPS自签名证书在iOS的应用中就解决了,其实整个配置过程就是浏览器中选择信任该证书的代码体现而已。

-(void)normalHttps{
    
    NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://localhost:8080/users"]];
    NSURLSessionConfiguration * config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSURLSession * session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    [[session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"%@,%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding],error);
    }] resume];
}

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
    
    NSLog(@"证书认证");
    
    //先判断证书是否有效
    if ([[[challenge protectionSpace] authenticationMethod] isEqualToString: NSURLAuthenticationMethodServerTrust]) {
        
        //证书验证请求
        SecTrustRef serverTrust = [[challenge protectionSpace] serverTrust];
        /**
         *  导入多张CA证书(Certification Authority,支持SSL证书以及自签名的CA)
         */
        NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"cert" ofType:@"der"];//自签名证书
        NSData* caCert = [NSData dataWithContentsOfFile:cerPath];
        if(!caCert) return;//读取证书文件失败
 
       //可以添加多张证书
        NSArray *caArray = @[caCert];
        //验证规则
        NSMutableArray *policies = [NSMutableArray array];
        [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()];
        SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies);
        NSMutableArray *pinnedCertificates = [NSMutableArray array];
        //进行自签名证书的添加
        for (NSData *certificateData in caArray) {
            [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)];
        }
        SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates);
        SecTrustResultType result = -1;
        //通过本地导入的证书来验证服务器的证书是否可信
        SecTrustEvaluate(serverTrust, &result);
        NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
        
        completionHandler(NSURLSessionAuthChallengeUseCredential,credential);
        
        return [[challenge sender] useCredential: credential forAuthenticationChallenge: challenge];
    }
}

你可能感兴趣的:(【从简】Express Generator搭建HTTPS前端框架)