Is there a middware, package, or general approach for having Laravel gracefully fallback to a session-less state if the session storage engine isn't available?
That is, let's say you have you a system using the database session engine. If that database goes down, Laravel's going to throw an exception whenever it can't connect to the database. I'd like a way to, instead, have Laravel not throw an exception, and just continue on without a working session engine.
(I realize this will mean careful coding on the application level to never assume sessions are available, but a pre thank you for all the warnings)
Use Case to Correct For:
Session storage system goes down temporarily (maintenance window, unexpected outage, etc).
Logged in user hits a page, sees Laravel error page because session engine can't connect
User is sad
I'd rather the user see some sort of normal web-page instead of a generic error message, even if that means we can't include stateful session data on the page.
That depends, Laravel does not persistently require a session engine to work, only on pages that actually use it. So that means that a fallback would basically not help - in fact an exception is the best thing Laravel can actually do to help you here.
Why? Because an exception can be cought and, if that is what you want to do (even though it makes little to no sense), be ignored.
Maybe I'm understanding you wrong, what exactly do you want to fall back to?
For me it's really hard to imagine how could it work and what you need it for. For example when you need user to be logged to access some page what should happen if session db or whole db is down? For me the only solution is show the user info that something gone wrong because it will be hard to pretend that website is working if it's not. So application throw exception, you catch it and display error page for user (and send site admin e-mail or sms)
If you would try to pretend you probably make your users angry because they would try to log in and they wouldn't be logged in without any info, so they would try 2nd time, 3rd time and finally they would think that your site is broken and would never come back again. In my opinion it's better to tell them something is wrong and "hey, come back here in about 2 hours"
Related
Right now, I am using the react-idle-timer library to log a user out after a period of inactivity. However, when I close all tabs or windows associated with my application and wait the idle period, then open up the webapp again, I am still considered an active user. I want to find a way to log a user out if they close the webapps after a certain period of time.
I tried using react-native AppState, but I started my app with create-react-app and I am having issues getting the application to react native.
Any advice?
If your user closes the browser tabs/window, it is like they are killing a process using the task manager: The application has no running instances anymore and there is no possibility to prevent this from happening. Therefore, it is not possible to achieve such a log-out mechanism using a client-side approach.
However, there are some possible solutions to this requirement to log out a user upon inactivity, which highly depend on the authentication mechanisms you use.
If your app is frontend-only (and has no dependencies to any backend services), you can have a „last active“ timestamp in local storage, compare and update it on each action and invalidate the users credentials if necessary.
For session-based log-in, you can make the session expire when the user closes the window (which should be the default behavior). Additionally, you can add a session variable similar to the „last active“ field, which is updated on each action and invalidates the authentication state from server side if necessary.
If you are using token-based authentication, you can tweak the token expiration period and regularly re-issue a new token (probably not best practice, but might be working…)
In general, in terms of security, you should always prefer relying on information saved on the server-side of your app rather than on the client-side. Information in the browser can be easily manipulated by an attacker, while checking for a forced log out on the server-side even works when the user decides to hard-reset their machine (or experiences a power outage, …). And if your server-side is not working anymore one day… well, then you have some bigger problems.
Regarding react and react-native, though they are working pretty much the same and are using the same framework paradigms, they have one major difference: They are compiling for different platforms. Therefore from my experience and from their technical foundation, it is neither easy nor recommended to use components of one of them for the other one. So it highly depends on your use case which of them to use best.
Even though this is not a safe & sound solution, I hope to give you some orientation on your possibilities for such a log out.
I am using watson assistant with flask framework. Once the session expires i get the following error
ApiException(response.status_code, error_message, http_response=response)
ibm_cloud_sdk_core.api_exception.ApiException: Error: NotFound: session id ba62bf14-87e-4c7b071b591e for agent instance 0e5c653c-9-b4e0-5a597c3e541e, Code: 404 , X-global-transaction-id: ffea409d54977b49
127.0.0.1 - - [03/Jul/2019 11:27:47] "GET / HTTP/1.1" 200
Refreshing the page does not create a new session
How to create a new session on this exception, so that I need not restart the local server ?
You mention a 5 minute session timeout.
Watson Plus trial has this set for just testing, and is not intended to be production level. It cannot be changed.
Standard version and lite can use session but both were originally stateless. You should use the V1 API for these. You will have to manage the state, but you will no longer have a time out.
If you are using the paid version of Watson Plus, or premium you can change the time out within the assistant settings.
You need to provide code, as any response will be blind and based on guesswork on what errors you have made, and there are many. But based on the fact that you failed to provide code, and still raised the question expecting someone to tell you what you did wrong then let's go with a rookie error.
I think you are creating the session as a global in your flask app, and maybe saving it it the app object. You probably have a route for the dialog, which makes use of the session. The code in this route, needs to catch the error, or test if the session is still valid, and recreate it. If you are catching the error, and trying to recreate the session, then you may have fallen foul of Python's global variable restrictions. Essentially if in a function you have a variable as the right side of an assignment, then its scope will be limited to the function.
Refreshing the web page, will not force the flask app to re-create the session. As you probably have that logic outside of any routes.
I'm implementing a non VOIP app in iOS 11. As per the nature of my App, I've implemented the startMonitoringSignificantLocationChanges(). All the implementation went well and it is working now.
while terminating the app I'm calling startOrReStartSignificantLocationUpdate()
and I'm restarting significantlocationupdate in didFinishLaunchingWithOptions
also I'm updating location in server in didUpdateLocations event
Location updates is reflected on my server when the App is in foreground or background. It is now reflects even if user kill the App manually. So it works with SLC but
the problem is;
Updates seems to get stopped after a period of time say, 3 - 4 hours. It happens if the user kills the App manually. As per the nature of my App, I need to get it re-initiated up on location change and get the location update to my server.
Is there any category of App which can get this location updates forever in iOS11? I'm thinking about how Moves App in iOS works. Not sure it works perfect with iOS11 though
If you only use “While Using” location access, as far as I understand nothing changes for you. If you use the “Always” access though, and you didn’t provide a “While Using” fallback as you should have… well, you will need to do that now
As Brad Jensen explains in the WWDC talk I mentioned, Apple has decided that forcing the user to give the app “Always” location access is a bad user experience:
Now, a second reason we think that many developers choose to require
Always authorization is they’re simply trying to give their users the
best possible experience (…) but this makes for a very poor user
experience for the users that don’t wish to grant the app Always
authorization. They are forced to choose between granting the app
Always, which is more than they would like in this example, or
granting it Never, which means they don’t get to benefit from any of
the app’s location-based features. And their final option is to grant
it Always and then revoke that authorization after they’re done using
the app. In any case, the user is not having a great time with this
app.
So, when you build your app using the iOS 11 SDK, you are now required to provide an NSLocationWhenInUseUsageDescription key in all cases (if you use location at all). For “Always” access, you can additionally provide a second key, which is now called NSLocationAlwaysAndWhenInUseUsageDescription. If you only provide NSLocationAlwaysAndWhenInUseUsageDescription but not NSLocationWhenInUseUsageDescription, asking for “Always” access will not work:
This app has attempted to access privacy-sensitive data without a
usage description. The app's Info.plist must contain both
NSLocationAlwaysAndWhenInUseUsageDescription and
NSLocationWhenInUseUsageDescription keys with string values explaining
to the user how the app uses this data
Effect on existing apps
Most SDK changes usually only take effect once you recompile your app with the latest version of the SDK & Xcode. This one is different: even if you don’t release any updates this summer, this change will affect you.
Here’s what the user sees when they run existing apps from the App Store in iOS 11 beta and they ask for location access:
The first one is from Foursquare, which has provided both access level options for a long time. In this case, iOS 11 lets you immediately choose “While Using” or “Always”, and since the description texts have not yet been updated with the new behavior in mind, it shows both texts at the same time.
The second one is from Topo Maps, an app that lets you browse hiking maps and find yourself on the map while you’re on the trail. You can imagine it has no reason to track you in the background, but still, the developer has not provided a “While Using” option. iOS 11 now lets you choose that option anyway, but since it might possibly cause some unexpected behavior in the app, it shows a warning that some parts of the app might not work.
If your app has only provided an “Always” key so far, I’d recommend that prepare a transitional update that adds the NSLocationWhenInUseUsageDescription key and makes sure the app works properly in this mode. That way, the user will get a popup like the one in Foursquare, which at least looks less scary.
This is more of a request for pattern and discussion rather than a simple one-off question. I have a backbone app where user can be part of different roles. The routes are defined as usual:
routes:
"": "showHomePage"
"import": "showImportPage"
I would like the import page to be accessible only to certain user roles. I imagine I can do something like this:
showImportPage: ->
if not MyApp.CurrentUser.can_import
return
Which indeed works. Of course, as you can imagine, this is easily exploited by just using Chrome console, and even if I don't show the link anywhere it's quite simple to just go in the address bar and type it.
Even though the above should be enough to stop a normal user, my question is: how could I secure that route from being accessed?
The opinion I have until now is that the only way is to refer back to the server before serving that route, either by checking a special URL or by simply re-fetching the User model before accessing... I have this hitch, though, that this will basically defeat the purpose of the whole idea behind a "single-page-app", if every url must be authenticated by the server and I need to show the usual ajax spinner before allowing the user to navigate... I know the amount of data going back and forward is minimal (only the json user info or even less), but still...
What are your opinion or solutions if you ever had to face this problem?
I think your question is a great one.
I made a PhoneGap app using BackboneJS and Jquery mobile so I faced the same problems you are facing now.
I think authorization can't live solely on the client side since it is inherently wrong. What lives at the client, is fully controlled by the client, and that's something no one can change.
Sending a request to the server does not break the single-app-page paradigm as long as the request gets the minimal data needed and all logic/view components are located on the client.
Keep in mind that if you have sensitive data in that page that you don't want regular users to see, it also must be sent from the server after verifying the authorization of the request, so it is not only a JSON of the user info that must be sent, it is the data itself as well.
I wish someone else would prove me wrong here, but as far as it goes for me that's the deal.
I have the following tiny dilemma: I have a backbone app, which is almost entirely route based, i.e. if I do to nameoftheapp/photos/1/edit I should go to the edit page for a given photo. The problem is, since my view logic happens almost 100% on the client side (I use a thin service-based server for storage and validation) how do I avoid issues of the sort of an unauthorized user reaching that page? Of course, I can make the router do the check if the user is authorized, but this already leads to duplication of efforts in terms of validation. Of course, I cannot leave the server side without validation, because then the API would be exposed to access of any sort.
I don't see any other way for now. Unless someone comes up with a clever idea, I guess I will have to duplicate validation both client and server-side.
The fundamental rule should be "never trust the client". Never deliver to the client what they're not allowed to have.
So, if the user goes to nameoftheapp/photos/1/edit, presumably you try to fetch the image from the server.
The server should respond with a HTTP 401 response (unauthorized).
Your view should have an error handler for this and inform the user they're not authorized for that - in whatever way you're interested in - an error message on the edit view, or a "history.back()" to return to the previous "page".
So, you don't really have to duplicate the validation logic - you simply need your views to be able to respond meaningfully to the validation responses from the server.
You might say, "That isn't efficient - you end up making more API calls", but those unauthorized calls are not going to be a normal occurrence of a user using the app in any regular fashion, they're going to be the result of probing, and I can find out all the API calls anyway by watching the network tab and hit the API directly using whatever tools I want. So, there really will be no more API traffic then if you DID have validation in the client.
I encountered the same issue a while ago, and it seems the best practice is to use server-side validation. My suggestion... Use a templating engine like Underscore, which is a dependency of Backbone, design the templates, and for those routes that only authenticated users or those with rights to do so, can access... you ask the server for the missing data (usually small pieces of json data) based on some CSRF token, or session_id, or both, (or any other server-side validation method you choose), and you render the template... otherwise you render a predefined error with the same template... Logic is simple enough...