Backend only alternative to javascript periodic function call? - javascript

I have the following in my js file that is included in the main .cshtml page of my ASP.NET MVC application:
var ajax_call = function () {
$.ajax({
type: "GET",
cache: false,
url: "/Session/Index/",
success: function (result) {
if (!(result.length > 0)) {
window.location.href = '/Home/Index/'
}
}
});
};
var interval = 1000 * 60 * .2; // where X is your every X minutes---.2 -> every 12 seconds
setInterval(ajax_call, interval);
The goal is to check if the session is still valid (the SessionController only returns a result if the session is active), otherwise the browser gets redirected to Home/Index, where HomeController has a global authorization attribute that redirects to the login page if the log in is not a valid session.
My questions are, is this a valid approach? It works (if I login in with a user, then open a new window and log in with the same user in the new window, the old window gets redirected to the login screen shortly after, depending on where it is in the 12 second cycle), but is there a way I can do such a thing entirely in the backend?
Thank you.

The goal is to check if the session is still valid
This is not a good approach, because a request to a server will rest the session timeout to 0. It means you are making session alive forever. If a user forgets to close the browser and leave the computer open, other can still access the account.
Here is the approach I use in my websites inspired by banking/credit card websites.
By default, Session Time out is 20 minutes (you can adjust the way you want). So, I let timer run at client side. When it reaches 19 minutes, I display a popup message with a minute count down timer.
If use does not close the popup, I redirect to logout page.
Here is the concept and sample code, but you do not need to use Telerik control to achieve it.

Related

How do I delete all cookies immediately after the browser is closed ( Using HTML and JavaScript )

What my site is and it's bare bones
A basic site made of HTML, CSS and Vanilla JavaScript. I am integrating front-end password protection to the site using JavaScript to check the credentials and assign a cookie which marks them as logged-in. It's just a side-project and security of the content isn't very necessary. The target audience also doesn't have the knowledge of adding cookies from the browser or manipulating the system in any way.
Once the user has signed in, they get redirected to the homepage, where the cookie is checked for. If the log-in cookie is present, they page loads, and if it's not present, the user gets redirected to the log-in page with a note asking to sign in. So far so good.
What's going wrong?
Like most web devs, I started testing the site before giving it a green signal, and turns out Chrome does not clear cookies after I close the browser. This is a spoilsport. Then, I tried using the onunload function on all the pages to delete the cookies, but the cookies are getting deleted even before the user reaches the homepage, and as a result, are directed to the homepage. I don't want to use Session Storage as opening the site in another tab does not take the Session Storage to the other tab.
Is there any way I could achieve deleting cookies when the browser is closed?
Since you're doing all this programming on the client-side, not the server-side, a cookie may not be the best approach - cookies are for transferring persistent information between the client and server. Local Storage may be a more appropriate choice, for controllable semi-persistent data stored on the client. Local Storage persists over different tabs on the same site.
A possible approach would be to have the saved data expire a certain amount of time after any page on your site has last been opened. For example, you could have, on every page, a script that runs every minute or five and sets the expiry time to an hour or 10 minutes in the future, or something like that - depends how much fine control you want over when logout occurs after inactivity. The code would look something like this:
// on pageload:
const advanceExpiry = () => {
localStorage.loginExpiry = Date.now() + 1000 * 60 * 10;
};
const loggedIn = localStorage.loginExpiry && localStorage.loginExpiry > Date.now();
if (loggedIn) {
advanceExpiry();
// every few minutes, push login expiry 10 minutes in the future:
setInterval(advanceExpiry, 1000 * 60 * 5);
} else {
// user has not logged in, or login has expired
localStorage.loginExpiry = 0;
// redirect to login page
}
and, on the login page, do localStorage.loginExpiry = Date.now() + 1000 * 60 * 10; followed by a redirect.
Just to point out, validation on the front-end is not remotely secure - but you already know about that and don't think it matters, which is fine.
There isn't a silver bullet readily available for your problem. However, using a Service Worker in conjunction with the Task Scheduling API and some JavaScript, you will reach close.
More info - Task Scheduling
Delete all cookies after an hour
function deleteAllCookies() {
var cookies = document.cookie.split(";");
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i];
var eqPos = cookie.indexOf("=");
var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT";
}
}
setTimeout for 1hour
function myFunction() {
myVar = setTimeout(deleteAllCookies, 3600000);
}
Call myFunction when user login's or when he or she starts the application.

Web Notifications API - Only show once per period

I'm writing a web app that needs to send notifications. It checks 12 different things every 30 seconds and if one of them meets the criteria it should send a notification; it then shouldn't send another notification until the next 30 minute (on the hour and half past the hour) interval. How do you check if a notification has already been sent and not to send it again? I thought this was done via tags but two notifications with the same tag will still pop-up, the second will just replace the first.
The function used to generate the notification is
function randomNotification(whoisit, tagtoPass) {
var message = whoisit + " is getting a notification";
var options = {
body: message,
icon: 'logo.png',
tag: tagtoPass,
}
var n = new Notification('Website Says:',options);
setTimeout(n.close.bind(n), 5000);
}
That function is called from another script that is loaded via Ajax every 30 seconds. That script checks the database to see if one of the 12 things is in a state that requires a notifications then calls the function and passes the name and a unique tag for that 30 minute interval.
Also I've noticed with this code, which was based on the developer docs from Mozilla on Notifications API, doesn't add the notification to the OS X Notification Centre.
Have you considered using a flag in localStorage to store the time when the last notification was sent?
Let's say that you store the time when you send the first notification, then check it again and if it's old enough you send another one and update that flag.
localStorage data will stay even if you refresh the web page.
Example:
localStorage.setItem("last_notification", timestamp)
localStorage.getItem("last_notification")
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

Java script, PHP

I have a scenario where I need to execute a logout function in php, this function deletes the user from DB and informs another application through sockets. This function should be called when the user closes the browser or tab. I have tried various scenarios posted by others and nothing seems to work in chrome(Version 57.0.2987.110) and firefox.
Following is the examples I tried along with links,
My sample Code
<script type="text/javascript">
var str = 'delete';// this will be set to 'Apply' if the form is submitted.
function logout(){
location.href = 'Logout.php';
}
function pageHidden(evt){
if (str==='delete')
logout();
}
window.addEventListener("pagehide", pageHidden, false);
</script >
Examples I tried....
// 1st approach
//window.addEventListener("beforeunload", function (e) {
/// var confirmationMessage = "Do you want to leave?";
// (e || window.event).returnValue = confirmationMessage;
// return confirmationMessage;
// });
// 2nd approach
// window.onbeforeunload = myUnloadEvent;
// function myUnloadEvent() {
// console.log("Do your actions in here")
// }
// 3rd approach
$(window).on('beforeunload', function() {
return 'Your own message goes here...';
});
checked the following urls
1. window.onunload is not working properly in Chrome browser. Can any one help me?
2. https://webkit.org/blog/516/webkit-page-cache-ii-the-unload-event/ - I followed this approach. Tried some other approaches as well.
3. I can't trigger the unload event in Chrome etc....
Any help is much appreciated, because if the user closes the browser an entry remains in the DB and this is not allowing any new user to login.
You shouldn't rely on JavaScript for sever-side code. It's actually entirely possible to achieve what you're looking for, purely with PHP. Just make sure to 'kill' the session before starting it:
session_set_cookie_params(0);
session_start();
session_set_cookie_params(0) will tell the browser that any exisiting session should only exist for another 0 seconds. Essentially, this means that a user will automatically 'log out' immediately. This way, you don't have to rely on client-side code, which is susceptible to all measure of interrupts such as power outages.
Hope this helps! :)
The correct way to logout is related to how they are logged in.
In PHP, the login state is typically managed by sessions. By default the timeout is 24 minutes of inactivity, but you can easily reduce it.
When a user logs out, you typically reset one or more session variables, and, while you’re at it, kill off the current session, and delete the session cookie.
However, you cannot rely on a user to log out, and many typically just wander off. This is why there is always a relatively short timeout on sessions.
If you want to automatically logout when the tab is closed, you will need JavaScript to intercept the process with window.onbeforeunload and then use Ajax to send the logout to the server.
As regards the database, you normally do not record the login state in the database. You may record the login time, and if you like, the logout time, but remember that may be never.

Sending Ajax Call When User Exits

I want to remove user stored data in my database when the user exits the page. A window dialog box will come up asking if the user really wishes to exit the page. Upon confirming to leave, an Ajax call should be sent to PHP confirming the action. Is it possible for PHP to receive the call in time and execute the command? If not, are there any other ways to verify that the Ajax call is sent successfully and the command is executed?
If you need very short-lived data (only relevant while the user is on the page), a database is not the right tool. Databases are designed to store long-lived data.
I suggest you use sessions instead. Here's a quick intro. Basically, sessions allow you to persist data across http requests, but to expire that data after a short while.
Start the session when the user logs in or opens your entry page, and store in $_SESSION any data you want to access while the user is on the page.
entry or login page
<?php
if(session_status()===PHP_SESSION_NONE) session_start();
... work through your script
//store data you'll need later
$_SESSION['username'] = 'Linda';
$_SESSION['age'] = 22;
$_SESSION['expires'] = time()+ 60*15; //expires in 15 minutes
The next time the user makes a request, test whether the session is still active. If so you can get the data from session, and refresh expiration. If the session has expired, you can destroy the data.
protected page
<?php
if(session_status()===PHP_SESSION_NONE) session_start();
if(isset($_SESSION['expires']) && $_SESSION['expires'] > time()){
//session is still active. extend expiration time
$_SESSION['expiration'] = time() + 60*15;
//retrieve data
$user = $_SESSION['username'];
.... run your script
}else{
//either the session doesn't exist or it has expired because the user
//left the page or stopped browsing the site
//destroy the session and redirect the user
session_destroy();
header('Location: /login.php');
}
You should not use unreliable, hacky and annoying methods. The only events that come close to your needs are window.onbeforeunload and window.unload but popups are usually blocked in those events (hence the hacky) and when blocked the remainder code as well.
There is also the issue that closing a tab will fire the events, closing the browser however will skip them and its all dependent if the browser actually supports it.
Perhaps use an ajax call every 5 minutes to detect if the page is still running and update a database with that time.
Now with a server cronjob you should select all rows with a time < now() - 300 and then you should have a list of browsers that recently connected but are not sending any signal anymore.
Or you could save the data in localstorage every 10 seconds so then there is no need to do all this?
Try This:
<script>
window.onbeforeunload = function (event) {
var message = 'Important: Please click on \'Save\' button to leave this page.';
if (typeof event == 'undefined') {
event = window.event;
//ajax call here
}
if (event) {
event.returnValue = message;
}
return message;
};
</script>

Counter Box, Visible for all clients

Hello I need a button for my website, that will start a countdown from 60 secounds to 0, then it should display some text (lets drink, cheers) and go back to start button.
All users must be able to see this countdown, so that when a user start the countdown other users can see this.
It should also display a counter, of howmany user have clicked the button, and joining in on the "button"
I have looked into this, but i need to do Ajax / javascript pulling.
Since my programming skill is still on copy/paste/edit level, I do not know howto get started, I can build the timer, but dont know howto do the pulling.
can anyone help me get started.
Regards
René
Well first of all, you need a stateful backend, to store a usercount. So php+any db.
you mentioned socket.io, build on nodejs.
With nodejs this aint this difficult, because its a single threaded runtime, so you can share variable values to different clients.
your nodejs have to listen to 3 urls:
for passing the basing page ( can be done without nodejs, just url to html)
ajax url for passing clicks on a button from client to backend, returns current count
ajax url to pass the current seconds, returns current count and connected users.
everytime the 2. channels gets called, you need to check , if the countdown is alrdy running. if not: start it, else increase clicked counter.
like this:
//nodejs code
var currendSeconds=60;
var connectedClients = 0;
var threadid;
function clientClickedButton(req, res){ // 2. url
if(currendSeconds==60 || ) {
threadid = setInterval(function(){
currendSeconds--;
if(currentSeconds == 0){
clearInterval(threadid);
}
}, 1000); //your counter
}
connectedClients++;
res.send(currendSeconds);
}
your clientside have to listen to click event on the button, send a ajax req to 2.url and display the returned seconds ( from now on our dont need to request the seconds, just set up a count down clientside, without requesting the current seconds. )

Categories