Worklight http adapter questions - ibm-mobilefirst

2 simple questions :
Do all http requests make thru http adapter do go thru the worklight server first?
If so then does it mean even a http adapter request to a public web site say a request to yahoo site for a stock price would also go thru worklight server first then next to the yahoo web site? If so then how do I make a http request without going thru the worklight server? I just want to go straight to yahoo web site without the "intermediate" server (i.e. workligth server)

1) Do all http requests make thru http adapter do go thru the
worklight server first?
Yes. Worklight Adapters work by executing JavaScript on the Worklight Server using Mozilla Rhino. You can read more about Adapters in the IBM Worklight Getting Started Modules. Look at Modules 5 and 6 for Adapter specific details. There are also code samples you can try next. The API documentation is in IBM InfoCenter. There is also a Developer Works article that talks about adapters that you may find helpful.
2) If so then does it mean even a http adapter request to a public web
site say a request to yahoo site for a stock price would also go thru
worklight server first then next to the yahoo web site?
Yes.
I just want to go straight to yahoo web site without the
"intermediate" server (i.e. workligth server)
IBM Worklight ships with jQuery, you can use the ajax method. Here's an example:
WLJQ.ajax( "http://finance.yahoo.com/d/quotes.csv?s=DOW+MSFT+AAPL+GOOG&f=snl1" )
.done(function (data) {
console.log(data);
});
Note that WLJQ is the namespace for the version of jQuery that Worklight ships. You can use jQuery or $ by doing: var $ = WLJQ; or var jQuery = WLJQ;.
You should get something like this back:
"DOW","Dow Chemical Comp",30.89
"MSFT","Microsoft Corpora",27.37
"AAPL","Apple Inc.",448.97
"GOOG","Google Inc.",790.13

If you use the adapter API on the client side then your request with go through the Worklight server. You can still make AJAX requests from the client side and skip the server. Essentially you'd be making server requests in the same way you would in Cordova, which means using a whitelist to allow your requests to access third party servers.

Of course You can access it directly without calling any adapter functions using simple jquery ajax calls.
$.ajax({
url: url,
data: data,
success: success,
dataType: dataType
});
or
$.get(url, function() {
alert( "success" );
})
.done(function() {
alert( "second success" );
})
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "finished" );
});

Do all http requests make thru http adapter do go thru the worklight
server first?
Absolutely not, it is entirely up to you. If you are using HTTP Adapters, then the HTTP request would be initiated from the Worklight Server and it would serve you back the response.
If so then does it mean even a http adapter request to a public web
site say a request to yahoo site for a stock price would also go thru
worklight server first then next to the yahoo web site? If so then how
do I make a http request without going thru the worklight server? I
just want to go straight to yahoo web site without the "intermediate"
server (i.e. workligth server)
If you are using a HTTP Adapter, then it would go through Worklight Server as per the first answer.
If you do not want the intermediate server, then you can use the conventional means of doing the HTTP request as you would do otherwise either through the Javascript /Ajax layer or natively (Android/iOS/Windows..)
Adapters are useful when it comes to security which Worklight uses to make sure that the request is initiated from the registered device - the authentication is done by exchanging device tokens etc.

I think you are missing an important point about the adapter architecture in WL. The adapter lives in the server, so by definition, any request you make with it will "go thru" the server. However, the information is not going through your WAS (or Tomcat) server.
Is there a reason you don't want to use the adapter? I would recommend using it since it makes it easier to pull down data, whether from a RESTful http call or database query.
If you did want to get around the adapter, there are issues with cross-domain authorization. I don't have much experience in this area, but you may be able to get around it using something like jQuery.ajax().

Related

identity server multiple issues after deployment

My current setup is like this. The entire project was built using the official docs here - https://identityserver4.readthedocs.io/en/latest/
API Server
Auth Server with local login, google login and github login
Console based c# client
JS based client
MVC based client.
(all of it, as described in the official docs)
Locally, all of them work beautifully. Able to login, access api endpoints, logout, redirect, the whole thing works smooth.
I have deployed all 5 of them to five different azure web apps. They all have the standard xyz.azurewebsites.net domains ready to use. Now, I have run into some problems.
the console C# client is able to talk to the deployed auth server, collect token using a local account on the auth server and make calls to the deployed API server. Based on this, I assume that both the api server and the auth server working hand in hand, as they should.
Problem #1 - the JS client keeps saying
'The login is blocked because of CORS Missing Allow Origin '
Problem #2 - the MVC client loads the auth server, and then the auth server gives me this error.
Sorry, there was an error : unauthorized_client
Request Id: 80005c0f-0000-eb00-b63f-84710c7967bb
Note : I have set the CORS policy on the auth server, both these clients, under client definition as follows. I am not too concerned about keeping the auth server open, so dont mind if any and every domain can call the auth server.
AllowedCorsOrigins = { "*.*" },
Also Note : I have set the URLS in the code before deployment. all loclahost:port number lines have been replaced correctly with the corresponding now published URLs.
So, what am I missing out here?
Update 1
I was able to solve the CORS issue. Have posted a answer here on another question.
Not able to enable CORS for identity server 4 in asp.net core
Update 2
So, now, both the JS client and the MVC client, are giving identical errors.
Sorry, there was an error : unauthorized_client
Request Id: 80005c0f-0000-eb00-b63f-84710c7967bb
Update 3
I have opened an issue which has log details.
https://github.com/IdentityServer/IdentityServer4/issues/4691
I am not sure if this counts as an answer, but posting for my own question, as it might might help others. Also, this is only a guess at this point.
I found out that the redirects were permanently stored in the database I used with EF migrations. That mean, local in memory redirects were being overwritten anyway by the database stored migrations. I believe this is the issue.
I also realized that the console app is working fine for it does not depend on redirect URLs where as the JS and MVC based clients dont work because they do depend on redirect URLs.
At this point, the best thing to do and for you (if you used EF migrations to store your auth server configuration) on database would be start over and switch to in memory only. Alternatively, you can try and update the database to suit your deployment requirements.
Ultimately, I believe, unless it is absolutely necessary, keep the auth server config (like redirects and CORS settings) in memory as they dont take up much value and are rarely changed.

Sharing the same code between several versions of the same Meteor web

I have a Meteor web deployed with Phusion Passenger integrated with Apache. The users access it with http://mycompany.org:3001.
That Meteor web communicates, via REST API, with another external server.
That external server has 3 versions of the same REST API:
http://external_server/v1/restapi
http://external_server/v2/restapi
http://external_server/v3/restapi
Each version of the above REST API manages a different user database, i.e. user_DB_1 -> v1, user_DB_2 -> v2, user_DB_3 -> v3.
Currently, my deployed Meteor web is making calls to the v1 of that REST API (http://external_server/v1/restapi).
Now, I have to call the other versions of the REST API (v2 and v3) with the same Meteor web, like this:
http://mycompany.org:3001/meteor_web_v1 (currently http://mycompany.org:3001)
http://mycompany.org:3001/meteor_web_v2
http://mycompany.org:3001/meteor_web_v3
Is it possible to capture the version of that URL and pass it as parameter to the Meteor web so that it calls the corresponding API?
For example, if the user make HTTP requests to http://mycompany.org/meteor_web_v1/login, then the web calls to http://external_server/v1/restapi, and so on...
Which is the approach here? Using maybe Apache mod_rewrite, Iron Router or which solution?
You can use either flow router or iron router to give you the url part as a parameter, you name it like this in your route declaration:
'/:myroute'
and then you will get a route parameter as a variable which you can use in your code to pass to your server method to do the http request.
You are doing the http request from the server, right ? Doing it that way prevents any CORS problems, and offloads the waiting to the server. The server should then update the database wth the received data, and the client will auto-refresh to make the results available.

How to run IBM BPM Rest api call from Post man client

I am trying to excute IBM BPM Rest api call from Post man client
Ex:
https://ustrial01.bpm.ibmcloud.com/bpm/dev/rest/bpm/wle/v1/user/current?includeInternalMemberships=true&parts=all
I set Basic Authentication values( Username, password)
I am getting status code as 200, but response i am getting some HTML code.
Can any one help me on this.Any help is greatly arreciated.
If you are getting a 200 status then why do you need the response? the status code should be good enough for you because 200 means the REST call worked fine.
I'm not familiar with the product you're referring to, but it sounds like you need to specify the media type you want to get back in an Accept header of your request. I suggest you try specifying
Accept: application/json
or (being an IBM product I'm guessing XML might be preferred)
Accept: application/xml
I tried to access BPM REST api call using Chrome's Postman & REST Console plugins.
Based on my experience, sometimes I don't no why it looks like Postman will not take auth details.
But, below steps always worked for me:
1. login to BPM account in Chrome,
2. open REST Console plugin and can access REST api GET/PUT all the time.
Hope this helps. Thanks
There are two parts to this answer, the 'long story short' part and the elaborate part.
Long Story Short:
IBM BPM Cloud exposes a variety of REST APIs to interact with its BPM engine and let it be as a service or more commonly known as 'Headless BPM' or 'BPM-as-a-Service'.
These REST API calls are secured by basic authentication i.e. by username/password
For Cloud, the username and password used for the REST API is not the same as the User's credential, which the User will use for logging into IBM BPM Process Portal or website. For on-prem solution, it is the same.
For Cloud, a 'functional' username password has to be requested for (Cloud Admin can create those) and that has to be used in the service call.
For example, if you are username/password for logging into BPM Cloud is 'johndoe#gmail.com/Test123' then there will be functional credential created for this ID (say, 'somefunctionalusernamedjohn123/8jdklajl23').
We can use this credential with every reqeust but what we should do is, use these credentials in the very 1st call to BPM server, in the response of which there will be a specific 'cookie'. We should save it and re-use that in our sub-sequent calls until it expires (you'll receive appropriate http status code if you disable 'follow redirect' in your http client config).
I had to raise a PMR to get this information. https://www.ibm.com/support/knowledgecenter/en/SSFPJS_8.6.0/com.ibm.wbpm.wle.editor.doc/topics/int_ext_services_start_process.html
Sample Java code to start a process:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://ustrial03.bpm.ibmcloud.com:443/bpm/dev/rest/bpm/wle/v1/process?
processAppId=3u092jr02j-fghjkyk.u078992c166c1&bpdId=25.jk8989-539a-4150-
b63e-ggui67868gjkgj7&action=start")
.put(null)
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.addHeader("Accept", "application/json")
.addHeader("Connection", "keep-alive")
.addHeader("Authorization", "Basic YXJrYX242232jklkljljLmNvbTpkZWZjb240QA==")
.addHeader("Cache-Control", "no-cache")
.addHeader("Postman-Token", "f46c1525-899-9897-uoh89-bb2b21a57f16")
.build();
Response response = client.newCall(request).execute();
Before finding this solution through PMR, I was desperately looking for a solution or a workaround. I noticed that my REST calls are getting redirected to an authentication page and I also noticed that, it is quite similar to what happens when you try logging into any IBM BPM Process Portal.
Once you login to IBM BPM Portal using Chrome, observe that it doesn't log you out. So I guessed the answer to be in the cookie and through trial and error, I picked up the cookie, which is PD-S-SESSIONID (named Something like that), and started using them in my service but obviously they expire in like 30-40 mins. So, I went ahead and used selenium and headless chrome to do the same thing as what I did manually. Anyway, this hack shouldn't be needed for On-Prem solution or with functional IDs for cloud.
Another very useful API wrapper which I have used in my project is:
https://github.com/egetman/ibm-bpm-rest-client. I had to make some changes to make this work with the trial account and for some other reasons.
And of course, we can't go far without the help of in-built REST API tester by IBM
e.g. https://ustrial03.bpm.ibmcloud.com/bpm/dev/bpmrest-ui/BPMRestAPITester/index.jsp
Thanks!

IBM MobileFirst: inspecting the HTTP adapter to back-end traffic

I am reaching a back-end from an HTTP adapter deployed in the MobileFirst Development Server with some unexpected results in the responses.
The back-end is outside of my control and uses HTTPS, so inspecting the back-end logs or the traffic with wireshark is not a option for me.
I'd like to be able to inspect the outgoing headers. Is there some way to do this?
Worklight Server to Backend
I think that easiest would be to switch to HTTP for the time of inspection (assuming it's not production-time), or to add a certificate to Wireshark in order to be able to inspect the network traffic even though it's in HTTPS
Device to Worklight Server
Assuming your request is not being sent via HTTPS as well, I believe you can see all sent headers in the Network tab inside Chrome's DevTools.
Depending on your Worklight version you may not see any of the queries being done.
In that case you could add the following in initOptions.js at the very bottom, and try again (but do note that this is unsupported and could change with any release w/out prior mentioning - use it only for the sake of this debugging session to see the queries in the Network tab log).
WL.androidProfileData[WL.EPField.SUPPORT_WL_NATIVE_XHR] = false;
WL.iphoneProfileData[WL.EPField.SUPPORT_WL_NATIVE_XHR] = false;
WL.ipadProfileData[WL.EPField.SUPPORT_WL_NATIVE_XHR] = false;
WL.windowsphone8ProfileData[WL.EPField.SUPPORT_WL_NATIVE_XHR] = false;
But if you're using HTTPS in all endpoints it might not help... consider changing to HTTP while developing the app?

How to know if a user is logged in from another service

I have a php/apache service and meteor on the same server. I am using the accounts-ui package.
Is there anyway to know in my php script, that a user is logged in, given the login token (session id?)
This is my original need: upload a profile picture for a logged in user.
Very simple right? But I have not found an answer after hours of googling.
First solution would be using html5 File apis to send data to meteor server and the server save the image. But this solution wont even work for IE9.
Second solution is what I am trying: Using a html form to upload picture to a php script (or whatever script, it can be a nodejs script if needed). This script will save the image like a traditional php script does. The thing is I cannot know if the upload request is authorized, otherwise everybody can change profile picture of anybody. I must add some information in the upload request and verify them in the php code before saving the image. I am thinking about sending a request from php script to meteor server but I need to know which parameters to send and how meteor responses it.
How can I achieve the second solution or if someone has a another solution for my origin problem that would be great.
Thank you.
Meteor uses an a protocol called DDP to communicate between the client and server. But as of now there isn't a PHP ddp client so you would have to use a REST type communication method between your meteor server and your PHP server.
If you feel you could build a PHP client for your meteor client, it would greatly help you as you could do stuff like run Meteor.call from your php scripts and have them subscribe to collections. The full DDP spec (pre1) can be found at : https://github.com/meteor/meteor/blob/master/packages/livedata/DDP.md
To do a REST method you should use Meteor Router to allow you to create server side routes. It is installed via meteorite which helps you access a list of community packages at [atmosphere.meteor.com].1
sever side js
Meteor.Router.add('/checklogin', 'post', function() {
var userId = this.params.userId;
var loginToken = this.params.loginToken;
if(userId && loginToken) {
return (!!Meteor.findOne({_id:userId,"services.resume.loginTokens.token":loginToken}));
}
});
You can then do a POST request with PHP to /checklogin with two params, one is userId which is the userId (found with Meteor.userId() or localStorage.getItem("Meteor.userId"). The other is the login token found via localStorage.getItem("Meteor.loginToken") on your Meteor client.