您的位置:首页 > 理论基础 > 计算机网络

react-native for android https证书认证

2017-11-09 23:25 323 查看

react-native for android https证书认证

react-native项目中,前端的请求其实都是调用原生插件发起的。
在android端,使用的是okHttp。


这篇博客是在react-native 0.47 + okhttp3 + tomcat的基础上讲解在本地生成自签名的https证书并给本地tomcat配置,再在android端配置证书认证,在前端fetch时请求本地https请求通过。

1、首先是https证书生成

我采用的是时jks文件,但我想jks可以,keystone文件应该也是可以的。jks和keystone文件生成过程不做描述。

利用jks文件来签发证书

在jks文件 同级目录执行命令:

keytool -export -alias server -file server.cer -keystore server.jks



-alias 后面填你选择的jks文件的 alias

-file 后面填你要生成的.cer文件的文件名

-keystore 后面填你选择的jks文件名

正确后回车则会要你输入口令,之后会在同级目录生成cer文件

这一步生成的cer文件就是用于android认证的证书文件

2、tomcat配置https

在你tomcat/conf/server.xml中,找到端口号8443的标签,默认是被屏蔽的,放开并修改为如下:


<Connector
port="8443"
protocol="org.apache.coyote.http11.Http11Protocol"
SSLEnabled="true"
maxThreads="150"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol="TLS"
keystoreFile="这里写你上面jks文件的路径(D:\test\test.jks)"
keystorePass="这里写你jks文件的密码(123456)"
/>


接下来你可以访问

https://localhost:8443/

浏览器第一次应该会显示如下



因为我们采用的是自签名的证书。点继续跳转到网页

如果出现tomcat的默认界面,说明访问正常,而且因为是我们自签名的证书,浏览器会显示会 不信任。

ok,http在pc浏览器请求通过,接下来就是在andorid应用内部。

3、react-native 项目应用在android端设置https

首页你可以直接在前端fetch你自己的https地址,你会发现返回结果是
network request failed,因为你访问的是一个不可信的https地址。
如果你去请求一个由权威机构颁发的证书的地址则可以请求到数据,比如你可以请求CSDN地址看看。


开始andorid端设置,首页前端的请求其实都是调用的原生插件,我们初始化一个rn项目时,会发现在MainApplication中会引入一个默认的package。

new MainReactPackage()

你点进去看会发现这里都是一些原生插件,如图片加载、权限模块、网络请求等等。

其中的 return new NetworkingModule(context);

就是封装的关于okhttp到前端调用的插件。

里面有多个构造函数,我们传进去的只有有个context,然后它又通过this指向四个参数的构造,其实多个构造最终指向的都是四个入参的构造函数,而传过去的OkHttpclient都是通过OkHttpClientProvider.createOkHttpClient()

而且OkHttpClientProvider还提供了替换clien对象的方法

OkHttpClientProvider.replaceOkHttpClient(client);

总之有两种方法

1、修改NetworkingModule.java文件

在里面为client添加证书认证。

如果你不知道怎么修改源码,那就需要第二种方法。

2、修改原生请求的引用

之前说了,它是把原生请求模块封装在NetworkingModule中,然后在MainreactPackage中引用, 我们完全可以把NetworkingModule.java文件移出来,然后在MainreactPackage中引用我们自己写的NetworkingModule.java类就行了。

将NetworkingModule.java文件的内容复制出来,将里面的

OkHttpClientProvider.createOkHttpClient() 都替换为

OkHttpClientProvider.getOkHttpClient()即可。

同时其中有个RequestBodyUtil.java类无法导入,也需要我们复制出来

再重写MainReactPackage.java类。

也是复制内容,修改其中NetworkingModule的引用即可。

然后将MainApplication中的MainReactPackage的引用修改即可。

前面这些修改都只是改了client对象的获取而且。 接下来才是对client对象的修改,即添加证书认证

// 证书认证

private void setCertificates(OkHttpClient.Builder client, InputStream... certificates) {
try{
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null);
int index = 0;
for(InputStream certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
if(certificate != null) {
certificate.close();
}
}
SSLContext sslContext = SSLContext.getInstance("TLS");
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
sslContext.init(
null,
trustManagerFactory.getTrustManagers(),
new SecureRandom()
);
client.sslSocketFactory(sslContext.getSocketFactory());
}catch (Exception e) {
Log.d("===", e.getMessage());
e.printStackTrace();
}
}

// 设置client对象并替换

private void httpsSetting() {
OkHttpClient.Builder client = new OkHttpClient.Builder()
.connectTimeout(30 * 1000, TimeUnit.MILLISECONDS)
.readTimeout(30 * 1000, TimeUnit.MILLISECONDS)
.writeTimeout(30 * 1000, TimeUnit.MILLISECONDS)
.cookieJar(new ReactCookieJarContainer());
try{
setCertificates(client, getAssets().open("这里填你放入assets目录下的cer文件名(test.cer)"));
client.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
// hostname 为服务器地址。ip或域名
Log.d("============", hostname);
return true;
}
});
} catch (IOException e) {
e.printStackTrace();
}
OkHttpClient.Builder builder = OkHttpClientProvider.enableTls12OnPreLollipop(client);
// 将上面设置了认证的client对象替换
OkHttpClientProvider.replaceOkHttpClient(builder.build());
}


然后只要在MainApplication中的oncreate生命周期调用httpsSetting()即可。你在前端就能通过fetch获取你tomcat里的数据

其实还有服务器对客户端的证书认证。即达到双向认证。

待续

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: