Store cookie even if the session is closed - session-cookies

What would be the best approach for a Play! application to remember the user? I think the only possible solution is to use the client side cookies, right? But as soon as the browser shuts down, this session is destroyed and not valid for the next request? How did/do you solve(d) this?
As for now, I ser the crypted userid in the session (per session), like this:
session("userid", user.id);
And then I use the interceptor to avoid passing parameters every when I need them oft, like described here: How to avoid passing parameters everywhere in play2?
But how to remember the user, or even beter, automatically log the user in on the next request?
EDIT: 2016-03-11
Be aware that some browser may store the session cookie for a longer period. For instance you can set in Chrome to remember the open tabs on next visit. This means that the Play Session cookie will be restored next time you open the browser.
And as of Play 2.4 the session cookie maxAge (you need to set in the application.conf) is renamed to: play.http.session.maxAge

To make the session not time-out when a users closes their browser you can use the session.maxAge parameter in the application.conf.
e.g.:
# Set session maximum age in seconds (4w)
session.maxAge=2419200

Quoting from Play 2.0 Session Documentation:
There is no technical timeout for the Session. It expires when the user closes the web browser. If you need a functional timeout for a specific application, just store a timestamp into the user Session and use it however your application needs (e.g. for a maximum session duration, maxmimum inactivity duration, etc.).
For security reasons, modern browsers will invalidate cookies on exit, and this is not something you can change simply because it would allow hackers to bad things with credentials that they do not rightfully have.
I would reevalutate whether or not you truly want the user to stay logged in, since it is usually a security risk to do so. If, however, you decide that you still want the user to stay logged in, you will have to try something that is not cookie based, and at the moment, I'm not sure what that would look like.

If you don't force a newSession or the user doesn't remove the cookies, the user should still be logged in.
It may be that your browser is set up to remove cookies when closing, or you are suffering from an external sideeffect. But I can confirm that cookies persist in my dev environment (in both Chrome and Firefox) after closing the browser.

I tried this and it worked for me. It's basically a composed Action.
def RememberAction(f: Request[AnyContent] => Result): Action[AnyContent] = {
Action { request =>
if(!request.session.get("email").isDefined && request.cookies.get("remember-email").isDefined) {
f(request).asInstanceOf[PlainResult].withSession("email" -> request.cookies.get("remember-email").get.value)
} else {
f(request)
}
}
}
Then you can use this Action in your controllers like this:
def index = RememberAction { implicit request =>
Ok("Hello World!")
}

Related

Can I prevent the updated script

I'm doing a Exam on a Web page works descending in advance so that if the time is up in question closes the question was the piece successfully through the following function
<script>
function countdown() {
> window.location.href="#Url.Action("TimeOver", "Answers"} )";
> }
setTimeout(function () { countdown(); }, 1000);
</script>
The bad thing is that when you refresh the page again restores the interim as if time did not end Can I bypass it, or is it inevitable fate
Short answer - no unless your users are authenticated.
If they are authenticated then you need to persist the timestamp that they first requested the question in your database. Disable browser caching and check for an existing timestamp on page load and check it against the time the answer is submitted. Anything done client side is not reliable, although usually delivers a better UX.
You could implement it using cookies and javascript if it's not mission critical, although this is easily bypassed by a power user, let alone a skilled attacker.

how to have per-session token value in struts2

How can we have persistent token value(or Form Key) during the valid session in struts2?
When <s:token/> is in the forms, after submitting the form, the token's value gets changed. It causes this problem that users can not open 2 browser tab and work with them(Only one tab is active due to the tokens' unique value per form).
how can I solve this with struts2 and have durable token value per session(Not per form)?
I think overriding the interceptor can solve the problem, but i wanna
to consider other options
Don't use token at all
If you require something per session, use the session itself. Token is meant to prevent request replay attacks. So just having one per session doesn't make sense.
I also had same problem, in my functionality there is preview which opens in new tab. User can preview multiple times, so it was throwing a token exception. I got one code as at start of function I wrote :
String downloadTokenName = TokenHelper.getTokenName();
String downloadToken = TokenHelper.getToken(downloadTokenName);
At end of function in finally I reassign token value as :
TokenHelper.setSessionToken(downloadTokenName, downloadToken);
It solved my problem.

How to redirect and reload the right way in Dart?

What are the preferred ways to do a redirection and a reload in Dart?
Do we just use: window.location.href = window.location.href?
There are a few different ways to handle URI changes and each have their own purpose.
When you want to send the user to another URI:
window.location.assign('http://google.com')
This one sends the user to Google, keeping the browsing history (the back button history). This is like clicking on a link.
window.location.href = 'http://google.com'
The same as above, just another way to do it. href is a setter, and causes the assignment to happen. I feel the previous version is cleaner.
window.location.replace('http://google.com');
However, the replace() method on LocalLocation object does not only send the user to Google, but also does not put the originating page in the session history, which means the user will not suffer from the never-ending back-button nightmare.
This is essentially the same as an HTTP redirect. The history is skipped.
When you want to do a reload/refresh.
window.location.assign(window.location.href)
Reloads the current page to the exact same URI. This does not contain POST data. Some of the resources (like images, etc.) may me reloaded from the cache, so it might not be a full reload.
This is essentially the same as pressing F5 and skipping the sending of POST data.
window.location.href = window.location.href
Again, the same as previous.
window.location.reload()
This way of reloading the page causes also the POST data to be sent. The "JavaScript version" of window.location.reload() also supports a parameter that specifies whether to skip the cache or not. However, the current Dart implementation does not support that parameter, and defaults to fetch the resources from cache.
This cache parameter may be added to Dart at some point, but it's not there yet. When it arrives, you most likely just pass true as the first parameter and then it would be like Ctrl + Shift + R.
Summary
I want to simulate a click on <a> tag.
Use window.location.assign(url).
I want to redirect to a new website like the HTTP redirection and skip the back-button history.
Use window.location.replace(url).
I want to do an F5 with POST data.
Use window.location.reload().
I want to do an F5 without POST data.
Use window.location.assign(window.location.href).
I want to do an Ctrl + Shift + F5.
Not available, maybe in the future. It would probably be window.location.reload(true).

How often is a Facebook Connect session refreshed?

I have set up Facebook Connect on my site, and the login is working fine. I have set up a listener to detect a login state change, as follows:
FB.Event.subscribe('auth.sessionChange', function() {
window.location.reload();
});
All good. Except that leaving a browser window open causes the page to reload after perhaps 20mins. So the auth.sessionChange is firing at some interval. Which can caused havoc, particularly if the last page was a POST form submission.
In the FB docs it says "Sessions are refreshed over time as long as the user is active with your app." How often is this session refreshed?
And how can I protect the page from reloading if it doesn't need to? A conditional maybe within that function??
EDIT - adding information for clarification:
I thought I would add some info to give those offering the advice some more to go on (thanks so far BTW):
the reason I have the listener triggering a reload is because I wanted users to be logged in to the site every time they visit - if they already had a session in FB. I was detecting an active session with the JS SDK, which I know could do log in on its own, but I needed to trigger a page reload after the JS had done the detection, in order to set a PHP session for the site - required step. I couldn't do the PHP login without first letting the JS detect the FB session in the browser.
Usually you can see the length of the validity of the session just by looking at the session itself. However in many cases, I suggest requesting the offline_access permission to ensure the access_token remains valid as long as the user doesn't change their password and doesn't remove your application.
Andy, if you are only listening for login state then subscribe to auth.login and auth.logout instead of auth.sessionChange.
If you need an active session for a user to take an action on your site, use FB.getLoginStatus() or FB.getSession() to check the session object.
http://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/
http://developers.facebook.com/docs/reference/javascript/FB.getSession/
It really depends on your App work-flow and the below is just a general approach.
You can have a flag that presents in all your pages (maybe in your main layout if you are using a template system) with a setter function to be executed once you don't need a page reload to happen. Something like:
var do_reload = true; // By default, we always allow a reload
FB.Event.subscribe('auth.sessionChange', function() {
if( do_reload ) {
window.location.reload();
}
});
// Call this whenever you don't want 'auth.sessionChange' to reload the page
function turnoff_reload() {
do_reload = false;
}
// Call this to return to default behavior
function turnon_reload() {
do_reload = true;
}
Now if you are "redirecting" the user (e.g.: after a form post) to a page that doesn't require a reload then you need to set the flag in the first line to false.
Another scenario if you have an ajax loaded content based on the user interaction, if the page reloads by itself that content will be lost and the user needs to interact again to view that content, what can be done here is setting the flag to false after the Ajax call.

Make a URL available only from within application

Say, I have a URL to edit a post .../posts/1/edit
I don't want this URL to navigate to a link when a user pastes it on his browser. However, if I have a link to this URL from within my application, the application should route to this URL.
Is it possible to achieve something like that?
I have no authentication system in the application.
I am just looking to see if there is an elegant solution to it. Else, I am sure I can find ways around. Thanks.
Use request.referer to get the page the user is coming from. This should allow you to achieve what you want. Note that this is not 100% reliable, sometimes the referer header might not be set. But in most cases it will work.
Alternatively, you can set a session variable that indicates whether the user is allowed (or not) to open a page (set a session variable on the main page with session[:allowed] = true, check its presence on the hidden page). When the user does not have a session variable set, render error or redirect to the main page (something like render :status=>403 and return unless session[:allowed]).
One of the easy ways would be send a unique header with the GET request and in the edit page, make sure you verify this header and only if it is present go ahead else throw a 401.
Ofcourse to make it much simpler, send a unique argument like /posts/1/edit?application="not-browser-1234"
and in edit page
if $_GET[application] != "not-browser-1234"
exit

Resources