How to implement concurrent session filter in grails to handle multiple login session? - authentication

For example: Suppose user "testuser#xyz.com" is login from one browser and performing some works. at the same time someone else login with same user "testuser#xyz.com" from another browser/machine in that scenario, i want to implement following ways
if the first logged-in user is not performing any action(inactive condition) from last 3-4 mins then first user will logged-out and second user will logged-in successfully.
If the first logged-in user is performing some task (active condition) then first user should get notification that, someone trying to logged-in from another browser/machine are you agree to allow ? if first user will allow then only second user will able to login(and first user should logout) otherwise not.
Any help is much appreciated.

This is not exact solution to your problem, but definitely it will give you the clue.
In your /grails-app/conf/spring/resources.groovy
//To enforce/restrict one session per user Starts
sessionRegistry(SessionRegistryImpl)
concurrentSessionFilter(ConcurrentSessionFilter, sessionRegistry)
registerSessionAuthenticationStrategy(RegisterSessionAuthenticationStrategy, ref('sessionRegistry')) {}
concurrentSessionControlAuthenticationStrategy(ConcurrentSessionControlAuthenticationStrategy, ref('sessionRegistry')) {
exceptionIfMaximumExceeded = true //False
maximumSessions = 1
}
sessionFixationProtectionStrategy(SessionFixationProtectionStrategy) {
migrateSessionAttributes = false//true
alwaysCreateSession = true//false
}
sessionAuthenticationStrategy(CompositeSessionAuthenticationStrategy, [concurrentSessionControlAuthenticationStrategy, sessionFixationProtectionStrategy, registerSessionAuthenticationStrategy])
//To enforce/restrict one session per user Ends
Source : searchcode.com

Related

Does Laravel query database each time I call Auth::user()?

In my Laravel application I used Auth::user() in multiple places. I am just worried that Laravel might be doing some queries on each call of Auth::user()
Kindly advice
No the user model is cached. Let's take a look at Illuminate\Auth\Guard#user:
public function user()
{
if ($this->loggedOut) return;
// If we have already retrieved the user for the current request we can just
// return it back immediately. We do not want to pull the user data every
// request into the method because that would tremendously slow an app.
if ( ! is_null($this->user))
{
return $this->user;
}
As the comment says, after retrieving the user for the first time, it will be stored in $this->user and just returned back on the second call.
For same Request, If you run Auth::user() multiple time, it will only run 1 query and not multiple time.
But , if you go and call for another request with Auth::user() , it will go and run 1 query again.
This cannot be cached for all request after first request has been made due to security point of view.
So, It runs 1 query per request irrespective of number of time you are calling.
I see use of some session here to avoid run multiple query, so you can try these code : http://laravel.usercv.com/post/16/using-session-against-authuser-in-laravel-4-and-5-cache-authuser
Thanks

Login as user without password (For an Admin Use-Case.)

To check if the view of a user is working or to make change out of the users view point (in development) it can be quite useful to incarnate a certain user.
How would I do this with Meteor? Best would be a solution which is independent of the Account Authentication.
To impersonate a user in production, you can call setUserId on the server, and Meteor.connection.setUserId on the client. For more details, see my blog post.
If you're using Meteor.userId() and Meteor.user() to identify your person in your javascript you could use something like this to override it at the very top of your client js
Meteor.userId = function (impersonate_id) {
return (impersonate_id) ? impersonate_id : Meteor.default_connection.userId();
}
Meteor.user = function (impersonate_id) {
var userId = Meteor.userId(impersonate_id);
if (!userId)
return null;
return Meteor.users.findOne(userId);
}
And now when you use Meteor.userId or Meteor.user modify your code so everywhere you use Meteor.user & Meteor.userId accepts an argument. So when you want to impersonate a user just pass it argument of the _id of the user you want to log in as
Meteor.user("1"); //Loads the data for user with _id 1
Meteor.user(); //Loads the actual logged in user
Also this will only work if you're actually the admin and your publish function allows you to see all your user's data

Laravel, get currently logged-in users

I want to display a list of currently logged-in users in an app. I want to use Laravel Auth method. I'm looking at the API and I cannot find anything like it.
I would probably need to loop through the sessions store and then match it to a user ID. Am I right?
UPDATE: Forgot to mention, I'm storing sessions in the DB.
"Currently logged in" is something you can't do with plain old sessions. Let me explain why:
A session is a bunch of data stored at server side which is assigned to an user through a cookie. That cookie remains on user browser and so it keeps the session active. Sessions can stay "alive" months without the user even logging in.
But, it's possible to store sessions on database.
As you can see, Laravel keeps a field called last_activity and, through that field, you should be able to retrieve all sessions that had activity within the last 15 minutes (or something else, you call it).
When your retrieve those records, the data field is a serialized representation of session data. You can unserialize($session_record->data) and retrieve the user id.
Depending on your Auth driver, session's user id may have different names:
For eloquent driver, it should be eloquent_login.
For fluent driver fluent_login.
For your Custom\AuthClass, it should be called custom_authclass_login.
Assume that all http requests from logged in users are passing auth middleware, we can override terminate function like following:
public function terminate($request, $response)
{
Auth::user()->save();
}
Then a query like User::where('updated_at', '>', Carbon::now()->subMinutes(12))->get(); will bring all logged in user, where 12 is the lifetime of session.
Of course, for real time, we should use ajax calls every 5 seconds or websockets via pusher or other.
First create a table where the logged in user's id will be inserted
Schema::create('active_users', function(Blueprint $table)
{
$table->increments('id')->unsigned();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users')
->onUpdate('cascade')->onDelete('cascade');
$table->timestamps();
});
Then in yourcontroller insert data while logging in
if (Auth::attempt($credentials)) {
DB::table('active_users')->insert(array('user_id' => Auth::id()));
}
and delete the data while logging out
DB::table('active_users')->where('user_id', '=', Auth::id())->delete();
Print the online users list in your view
<ul><strong>Online Users</strong>
<?php $online_users = DB::table('active_users')->where('user_id','!=',Auth::id())->get(); ?>
#foreach($online_users as $online_user)
<li>{{User::find($online_user->user_id)->first_name}}</li>
#endforeach
</ul>

In coldfusion: how to remember that a user has logged in?

I have a username/password on a login page, which goes to 'member' page. Basically, I used a statement that finds the number of rows in a SQL query, and if it's not 1 (the correct username/password combination), then it redirects back to the login page.
However, on the 'member' page, there are forms to do various things, like add new rows to a table using SQL, or return queries of joined tables. These forms also link back to this 'member' page, but the conditions for logging in (which requires a username variable and password variable) would no longer be met.
So, how do I get the server to remember whether a user is logged on or not?
In the application.cfm or application.cfc, you will need to enable sessionManagement = true so you can start tracking variables across page requests. Then when a user logs in, you will set a variable like isAuthenticated = true. Only redirect to the login page if the isAuthenticated = false or undefined (you can set a default using cfparam in onSessionStart of Application.cfm)
Rough example, assuming you are using ColdFusion 9+
Application.cfc
component {
this.name = 'myApplication';
this.SessionManagement = true;
public function onSessionStart() {
param name='session.isAuthenticated' default=false;
}
}
checkAuthentication.cfm
<cfscript>
if (!session.isAuthenticated) {
// send to login page
}
</cfscript>
In your login processing page, make sure you set session.isAuthenticated to true, and then it should skip checking / asking for the login. You can also look into the built-in authentication functions of CFLOGIN.
Hope that helps a bit.

nhibernate 'save' -> 'get' problem

HEllo,
I'm using nhibernate and have problems regarding user registration on my site.
When user wants to register I create new user record in the database and immidiatelly after that the system is logging the user in.
Well here lies the problem... When creating user record I'm using
NHibernateSession.Save(entity); //does not saves user object immediately to the database. It's kept in the session.
And when I want to log the user in, i load the user by his user name, and then I get null user object.
Why am I getting a null object and how can I make it work?
Thanks
Ok, I just tested this :
ISession session = s.CreateSession();
User user = new User();
user.Number = 122;
user.UserName = "u";
user.Id = 1;
session.Save(user);
User user1 = session.CreateCriteria<User>().Add(Restrictions.Eq("UserName", "u")).UniqueResult<User>();
session.Flush();
First the Select is being executed from the CreateCriteria and then on Flush the insert. So that's why it's not finding anything.
I also tested with Get<User>(1) and it returns the entity passed to the Save method - no query is executed.
Still - why query the database since you have the entity right there ?
Also, you say you use Get and then say you want to load by the UserName - is the UserName the primary key ? Get tries to load by the primary key.
If your Save and Get are done from different sessions then the Get will return null because the object only exists in the other sessions internal cache until it is flushed.
I'm not sure if an L2 cache would make a difference (I don't if L2 cache is written at Save or Flush).