I have two user: X and Y. And one page: Page Z. To access page Z I have a link.
If page Z is already open in user X browser I want the link to be disabled and denied the access to the page to user Y.
How can I do that?
Which language is the most apropriate to do that (jQuery, Php, etc)?
do not listen to any of these answers.
you can do this(although it is true that its kind of awkward)
you need PHP javascript (use j-query) and mysql. Your going to want to create a php script that gives the first user on a variable session, and every couple seconds or so your ajax will keep sending the db a script with php time(); when the second user comes on the php page will ask the db if there are any refreshes within 4 seconds, meaning that if the first user is still logged on there will be no more than a three second delay from the db time. and if there isn't that means the user is idle or has gone off the page and you can allow access. to redirect with php you can user the header function. If you are interested in EXACTLY how to do this upgrade my response and reply because it is pretty long and i do not want to write it for no reason.
this is the page you want people to go on:
$times = time();
$num = $times + 10000;
mysql_connect("localhost", "dbname", "password") or
die("Could not connect: " . mysql_error());
mysql_select_db("dbname");
$result = mysql_query("SELECT FROM $tablename WHERE areloggedin > $num);
$num=mysql_numrows($result);
if( $num < 0 ){
header('Location: http://redirectpage.html');
}else{
$times = time();
$con = mysql_connect("localhost","username","password");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("dbname", $con);
$qry = mysql_query("UPDATE
$tbalename SET
`areloggedin`= '$times'
WHERE id = $variable_seession_foruser ");
$result = #mysql_query($qry);
}
?>
(your html)
function ok(){
$.get("php/foo.php" , function(data) {
});
setIntreval(ok,3000);
//sepearate php file named foo.php
What you can is that create a boolean variable on server side and track it. When user if page Z is accessed by someone then set this variable true and while someone else is trying to open that link then check if boolean variable is true then stop them to redirect to that page and if it is false then take them to page Z. Once user left the page then set boolean variable to false.
This could be one way to achieve it but still I do not think that it is that straight forward. You will face many obstacles while implementing it.
just trying to come up with a quick implementation/workaround for something like this:
What you need
System-wide cache, (APC or SESSIONS won't do). You need something like memcached or redis so that multiple threads can access the same cache.
OR just a database+crontabs I guess (but cache is preferred)
PHP/Server-side scripting
Javscript-enabled clients
Strategy
Javascript makes an HTTP request every X (TTL) seconds. This request sets the key 'occupied' (in your chosen cache) to the clients IP with a cache-ttl of X+5 seconds. (If you opt for DB you'll need a cronjob reseting the entry every X seconds)
If a user tries to access the page and the 'key' !== their IP address, deny access.
Caveats
ONLY allow users to edit if they have JS enabled, display warning otherwise
Puts the trust in your users, they can bypass this easily.
Summary
Basically described an artificial keep-alive session using JS + cache, you can set the TTL to as long or as short as you want, depending on how actively the page is going to be edited.
Related
What I want to do:
I am trying to make a simple program that posts 5-10 statuses, at a time, on a page's wall. The post to the page will have to be done under the name of the page.
I've read tons of badly written Facebook Developers documentation and I'm reaching the point of confusion where I don't even know what questions to ask. So her I am.
My code so far:
I manually got the Page Access token manually, by this method:
Go to https://developers.facebook.com/tools/explorer
At the GET request form, down there, fill in me/accounts
You'll get a Javascript representation of your basic user data. Find the page you want.
Note the access_token and id fields, we're going to use them in the code below.
Thus, after getting the page Access token manually (And the ID of the page, of course)
import com.restfb.DefaultFacebookClient;
import com.restfb.FacebookClient;
import com.restfb.Parameter;
import com.restfb.exception.FacebookException;
import com.restfb.types.FacebookType;
import com.restfb.types.Page;
import com.restfb.types.User;
/**
*
* #author dsfounis
*/
public class FacebookConnector {
/* Variables */
private final String pageAccessToken = "GOT_THIS_FROM_THE_METHOD_ABOVE";
private final String pageID = "THIS_TOO";
private FacebookClient fbClient;
private User myuser = null; //Store references to myr user and page
private Page mypage = null; //for later use. In this question's context, these
//references are useless.
private int counter = 0;
public FacebookConnector() {
try {
fbClient = new DefaultFacebookClient(pageAccessToken);
myuser = fbClient.fetchObject("me", User.class);
mypage = fbClient.fetchObject(pageID, Page.class);
counter = 0;
} catch (FacebookException ex) { //So that you can see what went wrong
ex.printStackTrace(System.err); //in case you did anything incorrectly
}
}
public void makeTestPost() {
fbClient.publish(pageID + "/feed", FacebookType.class, Parameter.with("message", Integer.toString(counter) + ": Hello, facebook World!"));
counter++;
}
}
The problem:
The code above works. The thing is, it works temporarily. The page access token that I get has an expiration time of one hour, and I need to manually go through the process of obtaining it, every time that I run the program. What is the point of automating a process if I keep some aspects of it manual?
So I have to ask you: Can I do the process above programmatically, and obtain a fresh page access token at program launch?
Can I, maybe, use a better API to do something as simple as just post a couple of things on a Page's wall, every day?
My application is a console one, and I would like to stay away from implementing needless Logins, even though if you tell me that it is needed, it's going to be a bother I'll have to go through.
As a note: I've got the application registered in Facebook Developers, albeit only as a basic app. To get more permissions, I need to show proof of Facebook Login implementation, and as I say in the title, it's something I'll have to avoid.
There is no automatic process to obtain an access token. If there was, it will defeat the whole purpose of the OAuth flow. For pet projects and tests it's okay to use the Graph API Explorer but for public applications involving users it is mandatory that the user manually selects the login dialog.
Under your current scenario you can extend the user token using the method mentioned here https://developers.facebook.com/docs/roadmap/completed-changes/offline-access-removal/
Scenario 5: Page Access Tokens
When a user grants an app the manage_pages permission, the app is able
to obtain page access tokens for pages that the user administers by
querying the [User ID]/accounts Graph API endpoint. With the migration
enabled, when using a short-lived user access token to query this
endpoint, the page access tokens obtained are short-lived as well.
Exchange the short-lived user access token for a long-lived access
token using the endpoint and steps explained earlier.
https://graph.facebook.com/oauth/access_token?
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN
By using a
long-lived user access token, querying the [User ID]/accounts endpoint
will now provide page access tokens that do not expire for pages that
a user manages. This will also apply when querying with a non-expiring
user access token obtained through the deprecated offline_access
permission.
A simple program used only by the owner of the application does not need approval from Facebook.
e.g. https://www.facebook.com/phwdbot
I am trying to create a webapplication using Spring. The webapplication is a beta/demo site, which is invitation only. So, I need to generate a link to the webapplication url, appending a unique id, which would be valid for 24 hours. User can use that link for 24 hours and make use of the (I kind of also have plans of restricting the user by ip)
To achieve such token generation and expiry, should I just rely on the container with session time out to do it? or does it make sense to create spring backed service layer with token creation and expiry services?
EDIT
Now that I have a bounty on this to draw more attention, I thought I will rephrase the question so that it makes more sense - what would be a good strategy to force users out of a web application after a certain period of time?
Relying on session timeout would not be sufficient solution .
I am not acquaint with Spring . I would put my generic solution as below for any web application having requirement as yours :
Invitation is assumed to include a link to the Web Application .
The link is assumed to include the unique id .
The Beta/Demo user table is assumed to have a beta-expiry ( datetime ) column to hold the expiry date and time .
When your web application is accessed using the link in the invitation , update the beta-expiry column for that unique_id considering 24 hrs from then .
When a Beta/Demo user attempts to sign in , check the beta-expiry column for that particular user and allow access if the expiry is not reached . Display appropriate message in case of expiry .
Whenever a signed in Beta/Demo user performs subsequent accesses to your web application , check the beta-expiry column for that particular user and allow access if the expiry is not reached . Display appropriate message in case of expiry .
If seems useful , display a countdown timer showing the left over time somewhere in the header area .
In case of extension of Beta usage for all or a portion of users , you could update the beta_expiry column appropriately .
Additionally you could also have an invitation-expiry column to hold invitation expiry considering a particular duration for eg. a 48 hrs from when the invitation was sent .
We use a little bit similar solution to sign out ( signed in ) users from our SaaS application after a particular duration of no access .
I think that you should rely more in the back-end rather than a session on a cookie, imagine the case that you set the cookie for 24 hours expiration but the client deletes the cookies from the browser, (depending on your logic) your link will generate a new session or the request will be blocked.
IMHO you can store a session cookie on the client but you need to have a second source of comparison in the server, maybe a database, no-sql document, a collection in cache, something that you can compare and check the latest access to the client.
just to put all together imagine the following use case:
the user get the invitation link and click on it
the system check if the first time they log into the system, and save that date as a "start date" and another one as "last access"
the system sets an authentication cookie with 24 hours expiration
the system track every post back/ ajax call to the server and update "last access" date
if user deletes the cookie the system check the "last access" and make a comparison with the current server date
if valid the system creates a new auth cookie with the remaining hours
if not valid the system sends a message to the user.
for the user the cookie will expire according to the time left (calculation between start date and last access)
I hope this helps.
regards
One strategy is to keep track of expiry date-time of all the users by storing the relevant data in DB and using a cache library (to reduce DB hits while checking for the expiry date). Here is a small example:
Create a DB table with columns to map user id to expiry date: id, unique_user_id, expiry_date_time. You need to create the unique user id in your code and save it in DB before sending the URL to the user with this id. You can keep null as the initial value for expiry_date_time. Create a class to represent this mapping in Java:
class UserIdWithExpiryDate{
private String userId;
private Date expiryDateTime;
...
}
Define a Service with a cacheable method that will return an instance of this for a given userId :
public interface CacheableService {
#Cacheable("expiryDates")
public UserIdWithExpiryDate getUserIdWithExpiryDate(String id);
public void updateUserIdWithExpiryDate(String userId);
}
import org.joda.time.DateTime;
#Service
public class CacheableServiceImpl implements CacheableService {
#Autowired
private YourDao dao;
#Override
public UserIdWithExpiryDate getUserIdWithExpiryDate(String id) {
return dao.getUserIdWithExpiryDate(id);
}
public void updateUserIdWithExpiryDate(String userId){
Date expiryDate = new Date(new DateTime().plusHours(24).getMillis());
dao.update(userId, expiryDate);
}
}
The result of getUserIdWithExpiryDate method is stored into the cache so on subsequent invocations (with the same argument), the value in the cache is returned without having to actually execute the method.
Next step is to check the user's expiry date while accessing the site. This can be done using OncePerRequestFilter:
#Component("timeoutFilter")
public class TimeoutFilter extends OncePerRequestFilter {
#Autowired
CacheableService cacheableService;
// Here you need to decide whether to proceed with the request or not
#Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
filterChain.doFilter(request, response);
}
}
Steps that can be taken inside the doFilterInternal method to check the validity of the user:
Get the user Id from request
Execute: cacheableService.getUserIdWithExpiryDate(userId)
If step 2 returns null, there is no user present with this id. You should not proceed with the request.
If step 2 returns an instance of UserIdWithExpiryDate, check the value of "expiryDateTime"
If the value of "expiryDateTime" is null,it means user is accessing the site for the first time.Update "userExpiryDate":cacheableService.updateUserIdWithExpiryDate(userId) and proceed with the request.
If "expiryDateTime" is not null, compare this with current date_time. If expiryDateTime.isAfter(currentDateTime), proceed with the request.
For caching, you can use Spring Cache Abstraction with EHCACHE.
Tokens
For this marketing purposes we generate tokens upfront, store them in a database alongside all information like restrictions to certain user account, ip ranges (for certain mobile carriers), the date and time ranges of use and so on.
In case of one time codes we just mark it as being used in the database.
To generate those codes we use Random Numbers or encode some information and use (SHA-1 or better). Then we use bigInteger.toString(36) or a different scheme and group the first 16 letters to let it look like a license key.
If we express information with it like useraccount/name or carrier (mobile) or whatever we can even validate the token without a database.
Forcing User Out
Just check for the validity of the token the first time the user starts a session or logs in. Throughout the session you just check if the token has expired (store a value in the session if you have one, append it (encrypted) in the url or whatever or check against a database.
So on every request you just check if the user has permission to access your site otherwise you block the user with an error / info page.
You can also add a java script to each page. The script can determine whether the users permission to use your site has expired by:
Encrypt the relative time that the token is valid in a hidden div and calculate the absolute time using the users local time. Then compare the absolute expire time with the user time every now and than (lets say every 3 seconds) and you can yourself all those polling and pushing (comet, ajax, websockets) behaviour.
Once the java script program notice the token has become expired remove the content sections and replace it (or mark a hidden div as visible) with the info / error page content. This way every time the user revisits pages still stored in the browser history are destroyed also. (if this is a necessity for you).
Summary
Use random tokens and a database or encrypt information (like the day the token can be used) and SHA-1.
Check the tokens validity every time the user requests a page (store the timeframe in a session / url to save roundtrips to the database)
Provide a java script that destroys local pages in the history on revisit.
Here I can think of two use cases that I have seen.
1.) This kind of management is used in applications like online tests or email verifications, where user is provided a link with some token. This link and the token is valid for some fixed period of time and can be used only once. (Ex. online tests or password reset-emails)
2.) Another use case is to provide link with a token which are also valid for a fixed period of time, but in this case the link and the token can be used any number of time within the time period allowed (Ex. Online registration forms for test or some university enrollments).
So, definitely managing this using a session only will not be a good choice as the browsers can be cleared.
So you need to maintain the pair of the link and the token at the server (May be in a DB) with some other information like last accessed time, creation date and time, Valid upto .
To be more flexible validity time for link and the token can be set differently (eg. link can be used for a set of users, but the tokens are unique to a user).
So you can use this info on every user visit to check whether the link or token is still valid and what are their last accessed time. If it turn out to be expired then you can show the relevant error message.
What about "deleting the user's account" (depends on how you are building your logging system) after 24 hours.
Coupling this with checking user's account every time (s)he loads the page, will force him/her out at the first refreshing after the 24 hours threshold passses.
You can store the id with expiration time and when a request comes in with that id check if
it's still valid
and if you are trying to accomplish something like id is valid say 5 hrs after first request then store time when the first request is made and for each subsequent request check if it's still valid
During the Application startup , using the login Id of the User , i am making a Database call and loading all of his accounts and setting them in the session as shown
session.setAttribute("userinfo",userinfo);
and i am using this accounts information in the service layer to do a check before making a call to the Database
Now the problem is that if a User (who is having multiple accounts ) logs simulatunosly into a same browser , its creating same sessionid , as a result the session is having only the information of the last logged in user .
is there anyway i can solve this , may be the way i am storing data
please help
May not be the best solution but this will help to solve the problem.
What you could do would be to associate the userid with the sessionid and on every pageload / clicks, you will check if the sessionid matches the login user's userid. If it matches, disregard and run the page as usual else you can fetch the user info from the database and reassign the variables again.
You can use URL rewrite instead of cookies. The downside is that the session ID is exposed in the URL.
I'm doing an advertising network as a project for BS degree.
I;m trying to identify the same user across multiple websites. I have a USER table in my database with ID as an auto_increment number.
In the websites i'm tracking i included the following Javascript :
function OnLoad()
{
var requestURI = window.location;
var resolution = screen.width + 'x' + screen.height;
var colorDepth = screen.colorDepth;
var query = '?requestURI=' + encodeURIComponent(requestURI)
+ '&resolution=' + encodeURIComponent(resolution)
+ '&websiteid=' + encodeURIComponent(id);
document.getElementById("body").innerHTML = "<img src ='http://dan-vaio:8080/licenta/bannerimg.gif'" + query + " width = 500 height = 200 />"; // this is the place where i want to display my banner
}
On the server side A banner choosing algorithm is called and i get a queue of 5 banners that i want to display to this user. (only if the user acceseses the first time this website, otherwise i'd have to display the remaining banners in the queue. Haven't figured out how to do this either, could i keep the queue in a session ? ).
The question is : If i add a cookie to the response in the servlet, will it be avaiable when the same user acceses another website ?
i have this :
Cookie cookie = new Cookie("DisplayedBanners",visitedBanners); //
response.addCookie(cookie);
How can i uniquely identify an user? How to generate a unique ID to keep in the cookie and in the database, so when the same user accesses another website and calls my servlet i will know who he is.
Thanks a lot.
Banner queue will not work either if you use session for this. Session is maintained on the server. If you go to other site the same old session will not work here.
I would suggest that you keep this information in database.
So keep the last_shown_banner_tag with a user_id in a single table.
This table should be common among the websites.
Here it is explained how to do multidomain cookies, but in PHP (requires tweaking the Apache)
http://www.tutorialized.com/tutorial/Implementing-Cross-Domain-Cookies/372
I'm in little trouble with designing GWT application. I am trying to develope RIA app (with just one main widget, lets call it Main). First, user must be logged. Here's my way to do that, but it does have a problem, you'll see.
Show login components on root panel
If login was successfull (checks database), show Main widget
Widget is added to root panel
Everything works, but when you press Refresh it shows again login components ... It all happens in onModuleLoad method.
How should I redesign this logic? I'd like to let user logged (that means RootPanel will hold Main widget) for certain amount of time.
http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecurityFAQ
How to remember logins
Our login
system so far misses a useful feature:
For now it requires users to log in
again every time.
We can use Cookies to allow the user's
web browser to 'remember' the login.
In GWT, to set the cookie (which you'd
do right after your GWT code receives
the response as we did in the previous
code fragment):
String sessionID = /*(Get sessionID from server's response to your login request.)*/;
final long DURATION = 1000 * 60 * 60 * 24 * 14; //duration remembering login. 2 weeks in this example.
Date expires = new Date(System.currentTimeMillis() + DURATION);
Cookies.setCookie("sid", sessionID, expires, null, "/", false);
Now you can run the following code
right after your !EntryPoint begins
execution:
String sessionID = Cookies.getCookie("sid");
if ( sessionID != null ) checkWithServerIfSessionIdIsStillLegal();
else displayLoginBox();
Remember - you must never rely on the sessionID
sent to your server in the cookie
header ; look only at the sessionID
that your GWT app sends explicitly in
the payload of messages to your
server.
I'm not sure what how your GWT app implemented communication with the login service, but if you want to see another example, I followed the example here:
http://code.google.com/webtoolkit/doc/latest/tutorial/appengine.html#user
While it uses the Google App Engine as the backend authentication service, I think it's generic enough to be adapted to any server that supports the GWT RPC server side and has authentication services.
You need some kind of server-side support to do it.
For example, when user logs in, mark it in the server-side session. In onModuleLoad(), call the server to check whether user is logged in before showing the login form.
Other problems related to pressing Refresh can be solved with history tokens.