I define a Challenge Handler,
var AuthRealmChallengeHandler = WL.Client.createChallengeHandler("AuthRealm");
AuthRealmChallengeHandler.isCustomResponse = function(response) {
//returns true or false
};
once I click the login button i send a request to the adapter:
var resourceRequest = new WLResourceRequest(
"/adapters/AuthAdapter/getSecretData", WLResourceRequest.GET,
30000);
resourceRequest.send().then(getSecretData_CallbackOK,
getSecretData_CallbackFail);
However, after closing the app, re-launching and the login button is pressed again, the isCustomResponse is not called again. Why is it so?
I've checked that the isUserAuthenticated returns true, however it still doesn't call isCustomResponse:
WL.Client.updateUserInfo();
if (WL.Client.isUserAuthenticated("AuthRealm")) {
}else{
}
In addition to changing the project settings as was mentioned in the comments, to answer the remaining questions:
There is no relation between the application session "state" to JSONStore. JSONStore is local to your app itself in the device and not to the network.
You can invoke the logout function on application initialization, as a way to ensure that the client will be logged out once you have re-started the app in order to simulate the expected behavior by you. You will likely also want to extend the splash screen duration while this action is done so the user experience will be better... the logout function needs to simply call WL.Client.logout (refer to the documentation for this).
Related
I'm using the Google Identity Platform's OAuth 2.0 flow to authorize a javascript/HTML teacher observation form to write to a Google Sheets document. Everything is working well most of the time; however, last night one of our principals hit the following error:
"Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project."
I determined that he had launched the observation tool in the afternoon, and now maybe five hours later was trying to click the submit button. My hunch was that the token had expired, but from Google's documentation it seems like the JS auth library is meant to handle refreshing the access token as necessary - I believe it's not actually possible to get a refresh token to do anything manually.
I'm using what is essentially the sample auth code, and the app responds to being signed out appropriately. That is, if I sign out in another tab, the submit button is disabled and the sign-in button appears again. Assuming token expiration is the issue here, any ideas on the correct way to identify if the token has expired and how to request a new one, ideally without user interaction? Or if it's not an expiration issue, what else could it be? This user has successfully submitted data in earlier observations; it was just this one time when he waited ~5 hours (potentially losing internet connectivity / sleeping his laptop) during that time.
Here's the auth code:
var clientId = ""; //id removed
var discoveryDocs = ["https://sheets.googleapis.com/$discovery/rest?version=v4"];
var scopes = "https://www.googleapis.com/auth/spreadsheets";
var authorizeButton = document.getElementById('authorize-button');
function handleClientLoad() {
gapi.load('client:auth2', initClient);
}
function initClient() {
gapi.client.init({
discoveryDocs: discoveryDocs,
clientId: clientId,
scope: scopes
}).then(function () {
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
authorizeButton.onclick = handleAuthClick;
});
}
function updateSigninStatus(isSignedIn) {
if (isSignedIn) {
authorizeButton.style.display = 'none';
document.getElementById('submit').disabled = false;
findRow(); //find the empty row once we're logged in
} else {
authorizeButton.style.display = 'block';
document.getElementById('submit').disabled = true;
}
}
function handleAuthClick(event) {
gapi.auth2.getAuthInstance().signIn();
}
Thank you!
Similar issues that i had resulted in issues from that Authorized Javascript origins.
"In the Authorized JavaScript origins field, enter the origin for your app. You can enter multiple origins to allow for your app to run on different protocols, domains, or subdomains. You cannot use wildcards. In the example below, the second URL could be a production URL." taken from https://developers.google.com/identity/sign-in/web/devconsole-project.If prompt to view task came from an email, the email origin must be verified -or- the device is used for multiple accounts, the token will not stay. If the api is being improperly used, it will allow functionality for a short period of time , then fail.
This may be useful, in the authflow, you do not have scope or id in options
/** * Initiate auth flow in response to user clicking authorize button. * *
#param {Event} event Button click event. */ function
handleAuthClick(event) {
gapi.auth.authorize( {client_id: '[#app:client_id]', scope:
["googleapis.com/auth/calendar"], immediate: false}, handleAuthResult);
return false; }
I believe How to refresh expired google sign-in logins? had the answer I needed. Since all of my API calls happen at once, I added a new Date() when the page loads, a second new Date() when the submission flow begins, and if they are more than 45min (2,700,700ms) apart, I use gapi.auth2.getAuthInstance().currentUser.get().reloadAuthResponse() to force an access token refresh, as documented at https://developers.google.com/identity/sign-in/web/reference#googleuserreloadauthresponse.
Hopefully Google will eventually update their documentation to reflect this now-necessary step when using the auth2 flow vs the older auth flow.
Time will tell if this actually solved the issue, but I'm hopeful!
I hope it helps you friend that error is because you have the wrong time, you go to date and time settings then press synchronize now.
I've implement Firebase Authorization to login on my iOS app via Facebook and Google. I'm coding Swift.
When the app starts up I need to check whether a user is already signed-in in order to present the proper ViewController (e.g., if nobody is signed in I present the Login View Controller, otherwise I present the Home View Controller).
If I use the "easy" solution offered by Firebase, meaning
if FIRAuth.auth()?.currentUser != nil {
// User is signed in.
// ...
} else {
// No user is signed in.
// ...
}
So checking if the current user is not nil, it happens exactly what the Firebase guide (https://firebase.google.com/docs/auth/ios/manage-users) alerts might happen meaning
"Note: currentUser might also be nil because the auth object has not finished initializing. If you use a listener to keep track of the user's sign-in status, you don't need to handle this case."
So I would like to implement the listener as suggested in the guide:
handle = FIRAuth.auth()?.addStateDidChangeListener() { (auth, user) in
// ...
}
The listener will handle also intermediate status so that it is triggered when the Auth object is created. Point is I really cannot make it to work properly. Anybody can help me to use this listener in order to check if a user is logged in?
Thanks
I've implemented it like this:
FIRAuth.auth()?.addStateDidChangeListener { auth, user in
if let user = user {
// User is signed in. Show home screen
} else {
// No User is signed in. Show user the login screen
}
}
If you don't need the User object after checking, you can replace if let user = user with a boolean test, like this:
FIRAuth.auth()?.addStateDidChangeListener { auth, user in
if user != nil {
// User is signed in. Show home screen
} else {
// No User is signed in. Show user the login screen
}
}
Where to put the listener (from the comments):
For the cases I used to check if a user is signed in, it was enough to put it at the beginning of viewDidLoad in the specific view controller. But if you have any cases where you need to check every time you enter the specific view controller then it would be better to put it at the beginning of viewDidAppear. But I think in most cases you need to check only once, if the user enters the view
If you're setting up the StateDidChangeListener in application:didFinishLaunchingWithOptions, you'll notice that it fires once when the listener is attached (to set the initial state, which is nil when initialising) and then again once it's finished initialising (potentially not nil). This is intended behaviour, but really impractical if you're setting it up early.
An alternative to using the listener is using NotificationCenter. This will fire once initialisation has finished:
NotificationCenter.default.addObserver(forName: NSNotification.Name.AuthStateDidChange, object: Auth.auth(), queue: nil) { _ in
let user = Auth.auth().currentUser
}
I have a single-page JavaScript application and I'm using the Auth0 service for signup/login.
I have integrated the Lock widget and I'm saving a string to localStorage after a user is authenticated, like so:
lock.on("authenticated", function(authResult)
{
localStorage.setItem('login', authResult.idToken);
}
The problem is that when Auth0 redirects them back to my application after logging in, the authenticated event is fired only after page loaded, but by that time, I've already done the check to see if the localStorage string is set (which it is not); therefore, the user just keeps getting asked to login again:
if(localStorage.getItem('login') == undefined)
{
lock.show(function(err, profile, token)
{
// ...
}
}
I tried to see if there was anything special passed in to the page after a callback - but the referrer isn't always there.
If I don't automatically prompt the user to login, but instead show a login button - the authenticated event never fires for some reason.
How do I get around this?
Based on the information provided you seem to be using Lock in redirect mode and if that's the case you can use the hash_parsed event as a way to know if Lock found a response that it will process.
Every time a new Auth0Lock object is initialized in redirect mode (the default), it will attempt to parse the hash part of the URL, looking for the result of a login attempt. After that, this event will be emitted with null if it couldn't find anything in the hash. It will be emitted with the same argument as the authenticated event after a successful login or with the same argument as authorization_error if something went wrong.
Leveraging this event you could do the following:
Subscribe to the hash_parsed event:
If hash_parsed is emitted with null and localStorage has no indication the user already logged in then redirect to login.
If hash_parsed is emitted with a non-null value that either the authenticated or authorization_error will be emitted and you can react accordingly.
Some sample code:
lock.on("hash_parsed", function (response) {
if (!response && !localStorage.getItem('login')) {
// Redirect to the login screen
} else {
// Either the user is already logged in or an authentication
// response will be processed by Lock so don't trigger
// an automatic redirect to login screen
}
});
I have been following the documentation on React Native to build my app.
I am tyring to log a user in and be able to check if user is logged in or user data exists.
This is what i tried so far but i can't really see what i am doing wrong.
var starterApp = React.createClass(
{
user:{},
getInitialState()
{
console.log('initial state');
return {isLoggedIn:this.isLoggedIn ? this.isLoggedIn : 0};
},
componentWillMount()
{
console.log('will mount');
console.log(this.state.isLoggedIn);
//this.state.isLoggedIn = 1;
//this.setState({isLoggedIn:1});
//this.user= {name:'john', lastName:'doe'};
},
observe(){
console.log('observe');
},
componentDidMount()
{
console.log('mounted');
},
render()
{
console.log('rendered');
return (
<View style={styles.container}>
<Text>
{'YOOOO'}
</Text>
<Text>
{this.state.isLoggedIn}
</Text>
</View>
);
}
});
In componentWillMount funcion, i am setting the status and then commenting it out. After that when i refresh, It goes back to initial state. How can i persist the data of a user for next refreshes until i log him out. It needs to be persisting.
Thanks in advance.
AsyncStorage is the way to go.
You can use get/set methods to set storage keys based on your session information. I started off trying to use localStorage to store state, but whilst this works with debug sessions (if you are using chrome/safari to debug), it doesn't work when you run the app on an actual device.
A simple way to do it would be to use something like -
AsyncStorage.setItem('userSession', JSON.stringify(sessionData));
For when you want to save your session and -
AsyncStorage.getItem('userSession',
(rawData) => {
this.setState({session: JSON.parse(rawData)});
},
(error) => {
// whatever you want to do here.
}
);`
For when you want to restore it.
I'm using Fluxxor for my app at the moment, so I can choose which stores I want to save by cycling through them with AsyncStorage.multiSet. I can also restore all of them on initialisation of the app with AsyncStorage.multiGet.
The only thing I would caution you about is that the storage is asynchronous, so if you have an error it may be because you have initialised a part of your app before the AsyncStorage has given you a response. In the case of the app code that you are working on above, you may get a brief period of time where the app is rendered without the data, so you may need some kind of placeholder for that loading time, or delay rendering.
For storing whether a user is logged in, you general want to use sessions, where the users cookie will allow them to access a saved state on the server. The implementation of sessions will depend on what you are using for your server. For storing info not related to authentication, you can use local storage to save the user state.
I've managed to successfully log in FB using FB.Login function. Now I want to log out:
FB.Logout();
Debug.Log("FB IS LOGGED IN " + FB.IsLoggedIn);
I am expecting the above code to print the value of FB.IsLoggedIn as false and to ask me for a login and password on the next FB.Login.
In fact the value of FB.IsLoggedIn is true and I am not being logged out: next call to FB.Login does not ask for password and I am not being logged out when I open facebook site in my browser.
I've also tried to use the undocumented request to https://www.facebook.com/logout.php?next=[YourAppURL]&access_token=[ValidAccessToken] but it didn't make any effect for me.
How can I log the user out of facebook in my standalone unity application?
In fact what I need is to log in with different login and password.
Maybe I can invalidate the access token somehow which will cause the FB to ask me for login and password again?
Any help is much appreciated.
SDK version: 5.0.1
Build version: 140401.725cc2ecbc9002a
Unity Version 4.3.3f1 (c8ca9b6b9936)
I believe the FB.Logout operation is asynchronous, and the value of FB.IsLoggedIn would be true immediately after calling FB.Logout(). If you look at the documentation, it says:
You almost certainly should not use this function, which is provided
primarily for completeness. Having a logout control inside a game that
executes a Facebook-wide logout will violate users' expectations.
Instead, allow users to control their logged-in status on Facebook
itself.
Actually FB.Logout() has no delegate to let you know that account is successfully logout, so you have to create your own listner.
Secondly it will not sign you out from the actual device Facebook app or browser.
If you want to sign in with different account, so you can do by signing out explicitly from the app or browser.
Here is the code for how to detect that if you are logged out. It may useful to show Login and Logout button for Facebook that when to Login or Logout.
Here is the code from that you can determine the user has logged out within the Game.
public void OnFacebookLogout()
{
if (FB.IsLoggedIn)
{
FB.Logout ();
StartCoroutine ("CheckForSuccussfulLogout");
}
}
IEnumerator CheckForSuccussfulLogout()
{
if (FB.IsLoggedIn)
{
yield return new WaitForSeconds (0.1f);
StartCoroutine ("CheckForSuccussfulLogout");
} else
{
// Here you have successfully logged out.
// Do whatever you want as I do, I just enabled Login Button and Disabled
// logout button through this method.
EnableFacebookLoginButton ();
}
}
I'm not sure if it is correct but why not just do some while loop?
IEnumerator FBLogout (){
FB.Logout ();
while (FB.IsLoggedIn){
print ("Logging Out");
yield return null;
}
print ("Logout Successful");
}