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.
Related
Scenario:
1) login.php verifies the username and password and sets a session with the user id
$_SESSION['id'] = $id;
2) datatables / jquery calls an action.php file to fill the table with data
"ajax":{
url:"action.php",
type:"POST",
data:{action:'listTable'},
dataType:"json"
},
3) the action.php file calls the function listTable()
include('table.php');
$table = new table();
$table->listTable();
4) the listTable function (table.php) returns the whole data which is landing in the datatable
$output = array(
"draw" => intval($_POST["draw"]),
"recordsTotal" => $numRows,
"recordsFiltered" => $numRows,
"data" => $tableData
);
echo json_encode($output);
5) the data was selected with a sql command and was put into the tableData variable
Everything works fine in that case.
Ideas:
I wanted to acccess the session variable within the sql select command. This is not possible, because of the jquery / action.php api. Those are complete different files and have no access to that session. It is possible to set the user id within a hidden formular field, but this is not secure and easy to manipulate. A cookie file is also user editable. Furthermore Javascript cannot read server side session variables.
Question:
How can i use / access that php session variable in that scenario?
Update:
Thats not working too :/
overview.php
$userID = $_SESSION['id'];
data.js
"ajax":{
url:"action.php",
type:"POST",
data:{userID:userID, action:'listTable'},
dataType:"json"
},
table.php
$userID = $_POST["userID"];
I really don't understand here the problem, because of $_SESSION variable is available across the php files even if an ajax calls the php file. Until you call the AJAX call from the same browser and the ajax call includes the cookies (one of the cookie will be the session ID) then you will be able to reach your user ID in the SQL query on the PHP side, without passing to javascript/jquery your user's ID.
As you wrote in login.php:
$_SESSION['id'] = $id;
In your table.php where the SQL command is living:
echo isset($_SESSION['id']) ? "I'm existing!" : "I'm NOT existing!";
It will print "I'm existing!" if the user logged in and "I'm NOT existing!" if the user didn't log in. All the $_SESSION variables are available across the php files until the server gets the SESSION ID from the browser (which is a cookie). Cookies are automatically sent if you calling the same domain.
My authentication flow is as follows...
User visits my site and clicks login.
They are redirected to mydomain.auth0.com (or something like that), where they are prompted to login using either a username or password or a social provider e.g. Google.
Following the user's login, I run a custom rule in Auth0 to detect if they are a new user. If yes I now want to redirect them to a custom page to collect some additional data. I do this my implementing the following in the rule:
function (user, context, callback) {
context.redirect = {
url: 'http://www.example.com/profile'
};
callback(null, user, context);
}
This redirects the user back to my site adding a ?state=xyz... to the query string.
However, at this point I don't have a token or id token and seemingly no way to identify the user.
The example given at Auth0 talks about using this flow to force a user to update their password on login. However, for this to work there has to be some way to identify the user on the page they are redirected to.
What is the best way to get this working?
Here is a snippet from a Rule that redirects users to a post authentication registration page. Just pasting the section related to altering context.redirect since that is what you are asking about.
var hasPostRegistered = user.app_metadata && user.app_metadata.has_post_registered;
// redirect to consent form if user has not yet consented
if (!hasPostRegistered && context.protocol !== 'redirect-callback') {
var auth0Domain = auth0.baseUrl.match(/([^:]*:\/\/)?([^\/]+\.[^\/]+)/)[2];
var userId = user.user_id;
context.redirect = {
url: configuration.REGISTRATION_FORM_URL +
(configuration.REGISTRATION_FORM_URL.indexOf('?') === -1 ? '?' : '&') +
'auth0_domain=' + encodeURIComponent(auth0Domain) +
'&user_id=' + encodeURIComponent(userId)
};
}
Notice how the user_id is tagged on as a query param.
Note also, you can self-sign a JWT token inside a Rule, and send that to your redirect endpoint, which in turn can be configured to read / verify that JWT Token as a way to secure the redirection.
I am working on a .Net Core API, and inside my Controller, I have the following code:
if (User.Identity.IsAuthenticated)
{
var username = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
var user = await _userManager.FindByNameAsync(username);
artistCardDtoCollection = _artistsService.GetAllArtists(user.Id, User.IsInRole("Admin"));
}
The code above is because I wish to pass the User.Id (if logged in) and a IsAdmin flag to my GetAllArtists method.
The code above is failing on User.IsInRole("Admin"). I get a false when I know 100% that the user in question is an Admin. I've double checked the database via SQL Management Studio.
This makes me think one can't use User.IsInRole() when working with JWT. If that is the case, then what is the correct way? Thanks
Probably it could be the caching issue with User.IsInRole(), if we check documentation we will find:
IsInRole first checks the IsRoleListCached property to determine
whether a cached list of role names for the current user is available.
If the IsRoleListCached property is true, the cached list is checked
for the specified role. If the IsInRole method finds the specified
role in the cached list, it returns true. If IsInRole does not find
the specified role, it calls the GetRolesForUser method of the default
Provider instance to determine whether the user name is associated
with a role from the data source for the configured ApplicationName
value.
In your case you can try to use GetRolesAsync like below:
var user = await _userManager.FindByNameAsync(username);
var roles = await _userManager.GetRolesAsync(user);
artistCardDtoCollection = _artistsService.GetAllArtists(user.Id, roles.Contains("Admin"));
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
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>