I have already looked at all the answers on SO and other dev communities but all of them redirect to here, But being new to Android and Nativescript both I am not able to figure out where to implement this code.
Kindly help.
I am using Angular-http for my project, also this plugin has lot of open issues and is not regularly maintained, so It would not be advisable to use this in a project and get stuck at any point.
Hi @deepak4u2006,
I reviewed the attached links and implemented the described native code in NativeScript application:
import { EventData } from 'data/observable';
import { Page } from 'ui/page';
import { HelloWorldModel } from './main-view-model';
declare var java:any;
export function navigatingTo(args: EventData) {
let page = <Page>args.object;
var trustAllCerts =new javax.net.ssl.TrustManager(new X509TrustManager());
var myarray = [trustAllCerts]
let sc = javax.net.ssl.SSLContext.getInstance("TLS");
sc.init(null, myarray, new java.security.SecureRandom());
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
page.bindingContext = new HelloWorldModel();
}
class X509TrustManager implements javax.net.ssl.IX509TrustManager{
getAcceptedIssuers(){
return null;
}
checkClientTrusted(arg0, args1){
}
checkServerTrusted(arg0, args1){
}
}
You could test on your side the above-attached code and verify, whether the certificate will be ignored properly.
Let me know if you have some further problem with my implementation.
Hi @tsonevn
Sorry to raise such an old issue, I'm trying to deploy production app using a self signed certificate. For my purposes it will be secure since I control both the app and server.
I was just wondering if you had a clearer example of this code? I'm trying to implement it in javascript and have it work globally across my app.
Any help would be much appreciated.
Thanks!
Hi @sm1ddy ,
If I understand you correctly you are looking for a way to use provided from NativeScript HTTP modules together with an SSL certificate. If this is the case I would suggest using the nativescript-https plugin in the application, which will allow making HTTPS request.
Hope this helps.
I am also having difficulties connecting from my nativescript Android app to my own host machine running a SSL secured website. I have tried so much now. I see some references to the nativescript-https plugin, but I don't know how to use it in an angular-nativescript environment.
You cannot use the usual trick with javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory because the android client does not use this factory to create its sockets.
So you must use okhttp directly. Of course it is valid for Android only, so if you want to support ios you will probably have to create a sort of wrapper to use the angulat http client or okhttp depending on the platform.
Here is some sample code to initialize the client:
if (app.android) {
// create a SSL factory that supports self-signed certificates
const trustAllCerts = new javax.net.ssl.X509TrustManager({
getAcceptedIssuers: (): java.security.cert.X509Certificate[] => Array.create(java.security.cert.X509Certificate, 0),
checkClientTrusted: (arg0: java.security.cert.X509Certificate[], args1: string) => { },
checkServerTrusted: (arg0: java.security.cert.X509Certificate[], args1: string) => { }
});
const certs = [trustAllCerts];
const sc = javax.net.ssl.SSLContext.getInstance("TLS");
sc.init(null!, certs, new java.security.SecureRandom());
this.sslSocketFactory = sc.getSocketFactory();
const hostnameVerifier = new javax.net.ssl.HostnameVerifier({
verify: (hostname: string, session: javax.net.ssl.SSLSession): boolean => true
});
// build http client once
this.okhttp = new okhttp3.OkHttpClient.Builder()
.sslSocketFactory(this.sslSocketFactory, trustAllCerts)
.hostnameVerifier(hostnameVerifier)
.build();
this.jsonMediaType = okhttp3.MediaType.parse("application/json; charset=utf-8");
}
And how to execute a request:
private okhttpRequest<T>(method: "get" | "post" | "put" | "delete", url: string, options?: {
body?: string;
headers?: { [name: string]: string; };
params?: { [param: string]: string; };
responseType?: "json";
}): Observable<T> {
// build the request
const builder = new okhttp3.Request.Builder();
// method
switch (method) {
case "post":
builder.post(this.createOkhttpRequestBody(options && options.body));
case "put":
builder.put(this.createOkhttpRequestBody(options && options.body));
break;
case "delete":
builder.delete();
break;
}
// headers
if (options && options.headers) {
Object.keys(options.headers).forEach(key => {
builder.header(key, options.headers![key]);
});
}
// URL and parameters
if (options && options.params) {
const urlBuilder = okhttp3.HttpUrl.parse(url).newBuilder();
Object.keys(options.params).forEach(key => {
urlBuilder.addQueryParameter(key, options.params![key]);
});
builder.url(urlBuilder.build().toString());
} else {
builder.url(url);
}
const request = builder.build();
// make the call asynchronously and feed the response observable
const response: Subject<T> = new Subject(); // TODO manage unsubscribe to cancel the call
this.okhttp.newCall(request).enqueue(new okhttp3.Callback({
onResponse: (call: okhttp3.Call, resp: okhttp3.Response): void => {
const body = resp.body().string();
console.log(resp.code());
console.log(body);
resp.close();
this.zone.run(() => { // to allow UI change detection by angular
// if the response is OK, return the parsed body and complete
// TODO manage other kinds of response types
if (HttpWrapperService.isResponseOk(resp.code())) {
response.next(JSON.parse(body));
response.complete();
// otherwise return an error
} else {
response.error(new HttpWrapperErrorResponse(resp.code(), resp.message()));
}
});
},
onFailure: (call: okhttp3.Call, e: java.io.IOException): void => {
this.zone.run(() => {
response.error(new HttpWrapperErrorResponse(0, e.getMessage()));
});
}
}));
return response;
}
private createOkhttpRequestBody(body?: string): okhttp3.RequestBody {
if (body) {
return okhttp3.RequestBody.create(this.jsonMediaType, body);
} else {
return okhttp3.RequestBody.create(this.jsonMediaType, "");
}
}
I attached the type file for okhttp3 that you may put at the root of the project and reference in references.d.ts. okhttp3.d.ts.txt
You also must add the dependency to okhttp in app\App_Resources\Android\app.gradle:
dependencies {
compile 'com.squareup.okhttp3:okhttp:3.10.0'
// compile 'com.android.support:recyclerview-v7:+'
}
Good luck.
Hi @deepak4u2006,
I reviewed the attached links and implemented the described native code in NativeScript application:import { EventData } from 'data/observable'; import { Page } from 'ui/page'; import { HelloWorldModel } from './main-view-model'; declare var java:any; export function navigatingTo(args: EventData) { let page = <Page>args.object; var trustAllCerts =new javax.net.ssl.TrustManager(new X509TrustManager()); var myarray = [trustAllCerts] let sc = javax.net.ssl.SSLContext.getInstance("TLS"); sc.init(null, myarray, new java.security.SecureRandom()); javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); page.bindingContext = new HelloWorldModel(); } class X509TrustManager implements javax.net.ssl.IX509TrustManager{ getAcceptedIssuers(){ return null; } checkClientTrusted(arg0, args1){ } checkServerTrusted(arg0, args1){ } }You could test on your side the above-attached code and verify, whether the certificate will be ignored properly.
Let me know if you have some further problem with my implementation.
can you provide this code in JS?
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
You cannot use the usual trick with
javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactorybecause the android client does not use this factory to create its sockets.So you must use okhttp directly. Of course it is valid for Android only, so if you want to support ios you will probably have to create a sort of wrapper to use the angulat http client or okhttp depending on the platform.
Here is some sample code to initialize the client:
And how to execute a request:
I attached the type file for okhttp3 that you may put at the root of the project and reference in references.d.ts. okhttp3.d.ts.txt
You also must add the dependency to okhttp in app\App_Resources\Android\app.gradle:
Good luck.