I'm having a problem with wl.client.connect() and wl.client.logout().
If a user logs in successfully, a token and roles are remembered among other things. We save these vars while in our challenge handler functions of the wl.client.connect() auth.
But if they login, then shut down the app, opening the app again and trying to log in, I get a wl.client.connect() onSuccess, but since it has not gone through the challenge handlers, I don't get any tokens and roles that I need to save.
Do I need to, or is it possible, to run wl.client.logout() when they kill the app?
if you Quit your application manually then you can fire this API
WL.Client.logout("AuthRealm",{
onSuccess: function(){
WL.Client.reloadApp();
},
onFailure: function()
{ WL.Logger.debug("Error on logout");
}
});
on the other hand , you cannot detect the quit event of the app. it is really impossible
You can take a look at Cordova documentation for event listeners. The closest that I found would be "pause", which is triggered when you move the app to the background.
https://cordova.apache.org/docs/en/4.0.0/cordova/events/events.pause.html
You could listen for a pause and do a WL.Client.logout("<realm-name>").
Related
I am learning Feathers. I try to understand which event a server side Feathers Authentication module sends back to the client after it authenticates the user login information injected from the client (the connection is through socket.io).
Here is the background and the set up:
I created a copy of the example 'feathers-chat' app (https://github.com/feathersjs/feathers-chat) in the Guides on https://docs.feathersjs.com. The app works fine. I can login user at localhost:3030 from a browser. In the browser developer tools, I can see the websocket connection established by socket.io. Inside that connection, there are two events after clicking the login button in the browser:
The first event was sent from the browser to the server:
0: "create"
1: "authentication"
2: { strategy: "local", email: "user_email", password: "user_password" }
3: {}
I assume that the event name of this one is "create" and the rest information in 1-3 are event data.
The second event was sent by the server to the browser after login success:
0: null
1: { accessToken: "token...",
authentication: { strategy: "local", accessToken: "token...",payload: {...} },
user: {...}}
My question is: What is the event name of the second event? Is it null?
The reason for this question is that I try to use Postman to send and receive socket.io event data directly to the server during development. Postman needs a name for its event listener. I can send the first "create" event from Postman to the server successfully (the event was captured in the debugger on the server). But I can't figure out how to capture the second return event from the server in Postman. I created a listener called "null" but it doesn't work.
I'm trying to setup a manual flow for Facebook login, as per the docs at: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/
I've got my test Facebook app working as expected, i.e., I can login using a private web browser window fine. The URL I'm using is:
https://facebook.com/v3.3/dialog/oauth?client_id=<app_id>&display=popup&response_type=token&redirect_uri=https://www.facebook.com/connect/login_success.html
Now within my React-Native app, I'm using react-native-inappbrowser-reborn to present a SFAuthenticationSession on iOS. As per their docs (at https://www.npmjs.com/package/react-native-inappbrowser-reborn), I'm doing the following:
const redirectUri = "https://www.facebook.com/connect/login_success.html"
const url = "https://facebook.com/v3.3/dialog/oauth?client_id="+appId+"&display=popup&response_type=token&redirect_uri=https://www.facebook.com/connect/login_success.html"
InAppBrowser.isAvailable()
.then(() => {
InAppBrowser.openAuth(url, redirectUri, {
// iOS Properties
dismissButtonStyle: 'cancel',
// Android Properties
showTitle: false,
enableUrlBarHiding: true,
enableDefaultShare: true,
})
.then((response) => {
// Only gets to this point if user explicitly cancels.
// So this does not trigger upon successful login.
})
// catch handlers follow
Using the above, my app correctly open up an in-app browser and I can login fine using a test user for my test app. Upon successful login though, I don't get redirected back to the .then completion handler. It just stays in the in-app browser view and I see the same message from Facebook that I see when logging in using a web browser. It says something like "Success. Please treat the url the same as you would a password", or something like that.
I may be missing something here, but I thought the purpose of passing redirectUri as an argument to openAuth was so that upon redirection to that URI, the completion handler would be triggered.
Question: How do I redirect back to the completion handler upon login success?
I think that you already have a solution but thought it might be useful for someone else facing this issue. If you don't have a solution so far follow my instructions:
You can't directly redirect back to your application using deep link, since Facebook will not call a link `like myapplicationname://mycustompath´. It's only possible to call links using the https-protocol (https://...).
The solution I'd suggest you to use is to redirect using your own API (Facebook -> Your API -> Deep Link Redirection). You will understand why this is required in the most of the real world applications at the end of the instructions.
Starting from your react-native app call the authorize endpoint of Facebook with a redirection to your application and set the global deeplink of your app as redirect uri.
InAppBrowser.close();
InAppBrowser.openAuth("https://graph.facebook.com/oauth/authorize?client_id=YOURCLIENTID&redirect_uri=https://YOURDOMAIN:PORT/auth/facebook", "{YOURAPPSDEEPLINKNAME}://{SOMEPATHYOUWANTTOEND}")
.then((response) => {
handleAuthorized(response, LOGINTYPE.FACEBOOK);
});
Now after login you'll be redirected to your API with the authorization code token as query parameter (e.g. https://YOURDOMAIN:PORT/auth/facebook?code=AVERYLONGCODESENTBYFACEBOOK)
Using this code token from the query parameter, you make another API Call to get the access_token for the user
{GET}: https://graph.facebook.com/v15.0/oauth/access_token?client_id=YOUR_CLIENT_ID&redirect_uri=https://YOURDOMAIN:PORT/auth/facebook&client_secret=YOUR_CLIENT_SECRET&code=AVERYLONGCODESENTBYFACEBOOK
Facebook's API will send you an answer as JSON with the access_token inside.
You can make another call using the access token of the user, to get the userId and the username
{GET}: https://graph.facebook.com/me?access_token=ACCESS_TOKEN_SENT_BY_FACEBOOK_IN_PREVIOUS_GET_REQUEST.
If you need the e-mail address for the user you have to make another call. Make sure you'd set the permission to read the e-mail address for your app on the developer portal of facebook.
The following request will return you the id, name and the email of the user
{GET}: https://graph.facebook.com/USERIDFROMPREVIOUSREQUEST?fields=id,name,email&access_token=ACCESSTOKEN
I think you want to save all these information to a database and create a session in order to keep the user logged in and therefore all the requests described will be useful for you in a real application.
After doing all the backend stuff, you're ready for the redirection using deep link. To do that, set a meta-tag to redirect the inappbrowser to your application:
<meta http-equiv="refresh" content="0; URL={YOURAPPSDEEPLINKNAME}://{SOMEPATHYOUWANTTOEND}" />
We are facing an issue with the client timeout where the failure call is not getting invoked.
The issue appears as the following:
The user clicks on Sign in in our application.
After 4sec the user is able to login successfully to the app.
We recycle the Web services server and the user is taking 17sec to get the response back where it times out since we had set our time out to be 10000ms as our client requirements and it stays on the "Sign in" page without showing any error. On the second attempt to "Sign in" to the app, the response is coming in 4 sec and the app acts normally.
In the case of timing out we need to invoke a failure call to the user to inform him that error occurred and time out. but the call is not getting invoked:
initOption.js:
var wlInitOptions = {
.
.
// # Worklight server connection timeout
timeout: 10000,
// # Function to handle failure of Request Timeout
onRequestTimeout : function (error) {
WL.SimpleDialog.show(
"System Error: Request Timeout",
error,
[{text: "Close", handler: null}]
);
},
.
.
};
Worklight version 6.2
Please let me know if extra code sharing is required.
Thanks
Edite:
Application flow:
once the user launch the application it will connect to WL server, the user then will click on sign in button which will trigger and adapter method "Login".
once the login process is done, it will do another call to get user data and fetch them to the device.
As I described, when the user click on Login the app will try to invoke the authentication function from the adapter. we have set the time out for the application to wait for the response back to be 10sec as mentioned in the coed above.
If the application didn't get the response back, then We need to show the user a dialog box with the appropriate text.
The issue is getting resolved if I increased the timeout from 10sec to 30 sec. However, I need to keep the timeout 10 sec and show the user a dialog box on timeout.
The timeout value mentioned in the code is between the client and the server, but there is an additional timeout, between the adapter procedure and the backend; you will want to have these properly synced/aligned/timed.
Are you using requestTimeoutInSeconds in the adapter XML?
Read more here: IBM Worklight 6.0.0.1 - Timeout setting in Adapters
I'm trying to setup authentication using github.
I followed the documentation. I've installed the packages:
$> meteor add accounts-github
$> meteor add service-configuration
And my code in server/github.js looks like:
ServiceConfiguration.configurations.remove({
service: "github"
});
ServiceConfiguration.configurations.insert({
service: "github",
clientId: '****',
secret: '*************'
});
Meteor.loginWithGithub({
requestPermissions: ['user', 'public_repo']
}, function (err) {
if (err)
Session.set('errorMessage', err.reason || 'Unknown error');
});
When I start meteor now I get the following error:
/Users/me/.meteor/tools/5bf1690853/lib/node_modules/fibers/future.js:173
throw(ex);
^
TypeError: Object #<Object> has no method 'loginWithGithub'
at app/server/github.js:11:8
at app/server/github.js:18:3
....
So it seems the Meteor object doesn't have the loginWithGithub method. Any suggestions why?
You are running the code in the /server directory of your app.
Usually you call this code from the web browser to make Meteor display the Github OAuth login dialog.
This is not available on the server since its only meant to work on the browser side. This is why you see this error.
You would usually fire Meteor.loginWithGithub() in the event listener for when they click a button or some UI element to begin the login process.
Another thing to keep in mind is Session (Session.get, Session.set, etc) only work on the client too.
To see which methods run where use the Meteor documentation. In the top corner of each method it shows where the code can run: Client, Server or Anywhere.
I have a Worklight 6.1.0.1 hybrid app that I'm running on iOS. The app uses adapter-based authentication. The app prepares the invocation data makes the following call when the Login button is clicked:
singleStepAuthRealmChallengeHandler.submitAdapterAuthentication(invocationData, {});
If the WL service is down, or if the mobile device has no network access, the invocation will timeout. I see the following in the Xcode console:
defaultOptions:onFailure Request timed out for http://myipaddress:10080/myapp/apps/services/../../invoke. Make sure the host address is available to the application (especially relevant for Android and iPhone apps).
How can I capture this timeout event, so that I can update the UI with a proper message?
Update May 23rd based on comments:
What is your exact flow?
You should first use WL.Client.connect({onSuccess: ..., onFailure:...});
If connection to the server is successful, you will enter the challenge handler. Otherwise, you will enter onFailure and there you can create the custom error handling.
Previous answer attempt:
The below is when trying to connect() to the Worklight Server.
If you want custom handling for when the client fails connecting to the server I believe you need to enable and use the option onConnectionFailure in initOptions.js:
var wlInitOptions =
// # The callback function to invoke in case application fails to connect to Worklight Server
//onConnectionFailure: function (){},
}
Otherwise, Worklight's default dialog will be displayed.