Set AuthComponent when doing a manual login with AJAX - ajax

Using CakePHP 2.0, when logging in the normal way, a helpful set of cookies is set and accessible via AuthComponent::user(). However, this does not get set when doing it the AJAX way. The verification works fine, but I would like to figure out how to set AuthComponent without a hard refresh.
Maybe I could do without AuthComponent and just store cookies, but I wanted to check to see if there's an easy way to do this before doing all of that work.
I've checked the JsHelper and Authentication pages in the CakePHP 2.0 documentation.
Any ideas?

Why dont you create a function in the user around the lines of:
public function autologin() {
$this->autoRender = false;
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$cuser = $this->Auth->user();
$this->Session->write('Udata', $udata);
$fD = array('loggedIn'=>true,'vdata'=>$udata);
} else {
$fD = array('loggedIn'=>false,'vdata'=>'Your username/password combination was incorrect');
}
echo json_encode($fD);
}
}
and call this page with your ajax. with the JSON run some check;

Related

Cookie-less Laravel sessions

We have a small quiz type functionality built in Laravel to be embedded in a site via an iframe served from a separate domain (to work around CMS limitations).
It uses sessions to keep track of the user's progress in the quiz. This doesn't work in Safari (Mac/iOS), I believe because Apple disable cookies issued from within an iframe.
Assuming that limitation is one we're stuck with, has anyone had any success making Laravel sessions cookie-less? I found this code on Github, which looks promising but is old enough (and incompatible with current Laravel) that I can't tell if it's going to be a solution.
In case it helps someone else, or anyone can see any silly errors in my code, this is what I did (an adaption of the Github code, to work in Laravel 9).
I extended StartSession and SessionServiceProvider (to use my new StartSession). I created an override for handleStatefulRequest in Start Session, and where it adds a cookie to the reponse (it calls addCookieToResponse) did this:
if ($request->cookies->get($session->getName())) {
$this->addCookieToResponse($response, $session);
}
else {
// Add session ID to header
$this->addIdentifierToResponse($response, $session);
}
That new function looks like this:
protected function addIdentifierToResponse(Response $response, Session $session)
{
if ($this->sessionIsPersistent($config = $this->manager->getSessionConfig())) {
$response->headers->set("X-Session-Token", $session->getId());
}
}
I also changed the getSession method to get the session ID from that newly set header (when no cookie found):
public function getSession(Request $request)
{
return tap($this->manager->driver(), function ($session) use ($request) {
if ($request->cookies->get($session->getName())) {
Log::debug('1. Set session ID from cookie');
$session->setId($request->cookies->get($session->getName()));
}
else if ($request->headers->get("X-Session-Token", $request->input("sess_id"))) {
$sessionToken = $request->headers->get("X-Session-Token", $request->input("sess_id"));
$session->setId($sessionToken);
}
});
}
I created a Github repo containing the whole thing.

Best practice passing data to view model

I have a login view which lives in its own shell. Also I have adjusted the HttpClient to automatically redirect to the login shell if any http request returns an unauthorized state.
Additionally I'd like to show some textual info to the user on the login page, after he has been "forcefully" logged out. How can I pass the information (logoutReason in the code below) from MyHttpClient to the login shell/view model?
Here's some conceptual code:
login.js
// ...
export class Login {
username = '';
password = '';
error = '';
// ...
login() {
// ... login code ...
this.aurelia.setRoot('app'); // Switch to main app shell after login succeeded...
}
// ...
}
MyHttpClient.js
// ...
export default class {
// ...
configure() {
this.httpClient.configure(httpConfig => {
httpConfig.withInterceptor({
response(res) {
if (401 === res.status) {
this.aurelia.setRoot('login');
let logoutReason = res.serversLogoutReason;
// How should i pass the logoutReason to the login shell/view model?
}
return res;
}
}});
};
// ...
}
Solution:
I've chosen to take the "event" path as suggested in bluevoodoo1's comment with some adjustments:
MyHttpClient fires/publishes a new HttpUnauthorized event which holds the needed information (description text, etc.)
MyHttpClient doesn't change the shell anymore since the concrete handling of the 401 shouldn't be his concern
login.js subscribes to the HttpUnauthorized event, changes the shell & shows the desciption text...
I'm still open to any suggestions/improvement ideas to this solution since I'm not quite sure if this is the best way to go...
You could set a localStorage or sessionStorage value and then clear it after you have displayed it. What you are asking for is known as a flash message where it displays and then expires.
Within your response interceptor add something like the following:
sessionStorage.setItem('message-logoutReason', 'Session expired, please login again');
And then in the attached method inside of your login viewmodel, check for the value and clear it, like this:
attached() {
this.error = sessionStorage.getItem('message-logoutReason');
sessionStorage.removeItem('message-logoutReason');
}
Then in your view you can display it:
${error}
As Bluevoodoo1 points out, you could also use an event, but I personally try and avoid using events as much as possible, harder to test and debug when things go wrong.

Anyway to redirect to previous URL after registration in Joomla?

I am developing a component that required login at some level, then if user is not logged in, I placed a login link, that take user to login page with following in query string.
return=<?php echo base64_encode($_SERVER['REQUEST_URI']);?>
After login, it comes back to that page, but is there some way to tackle this if user is not registered and user starts registering? Is there some way to do this without changing some thing in Joomla it self? like by just setting some thing in cookie e.t.c. Or I will need to change some thing in Joomla Registration component or module. Or is there some plugin for that?
Any response will be appreciated, please tell what ever way you know so that it may give me some better clue.
In your component you could try to store the referrer in the Joomla! session - I don't believe the session changes or is replaced during login. I haven't had time to try this but it should work.
To Save:
$session = JFactory::getSession();
$session->set('theReferrer', $_SERVER['HTTP_REFERER'], 'mycomponentname');
To Retrieve:
$session = JFactory::getSession();
$redirectTo = $session->get('theReferrer', '', 'mycomponentname');
Then you can just use a setRedirect before you return.
$this->setRedirect($redirectTo);
You can achieve this with a plugin (at least in Joomla 3.x - not sure how far back this will work off-hand). Key here is the onUserAfterSave event, which tells you whether the user is new or existing.
I wrote the code below some time ago, so can't recall the exact reason the redirect could not be done from within the onUserAfterSave event handler, but I think the redirect is subsequently overridden elsewhere in the core Joomla user management code if you try to do it from there, hence saving a flag in the session and checking it in a later event handler.
class PlgUserSignupRedirect extends JPlugin
{
public function onUserAfterSave($user, $isnew, $success, $msg)
{
$app = JFactory::getApplication();
// If the user isn't new we don't act
if (!$isnew) {
return false;
}
$session = JFactory::getSession();
$session->set('signupRedirect', 1);
return true;
}
function onAfterRender() {
$session = JFactory::getSession();
if ($session->get('signupRedirect')) {
JFactory::getApplication()->redirect($_SERVER['HTTP_REFERER']);
$session->clear('signupRedirect');
}
}
}

CakePHP 2 AJAX redirections

I'm using AJAX in my web-app stuffs like search but if the user has been logged out, the ajax function return nothing because the redirection (from the action 'search' to the action 'login') has not been handled correctly.
Is it possible to redeclare the method 'redirect' in AppController to render the right action when a redirect hapend in an AJAX call ?
Thank you,
Sébastien
I think your best bet would be to setup you ajax to call to respond correctly to an invalid response. As it seems to be an important part of your app I would pass a 'loggedin' variable with every ajax request, so the client can tell as soon as the user has been logged out.
Update
In the case you want to keep a user logged in, you simply have to put the logged in/cookie check in something like your AppController::beforeFilter() that gets run with every request. for example:
public function beforeFilter() {
if($this->Auth->user() {
// USer is logged in, it's all gravy
} else {
// User is not logged in, try to log them in
$userData = $this->Cookie->read('User');
if(!empty($userData)) {
// Function that grabs info from cookie and logs in user
}
}
}
This way there will be no redirect as the user will be logged in as long as they have a cookie.
Another approach would be to allow everyone access to the Ajax function:
public function beforeFilter() {
$this->Auth->allow(array('my_ajax_method'));
}
And then check the user is authenticated in the method itself:
public function my_ajax_method() {
if (!$this->Auth->user()) {
//user not authenticated
$result = "requires auth";
}
else {
// use is authenticated
// do stuff
$result = 'result of stuff';
}
$this->set(compact('result'));
}
You will need to check the result of the ajax call in your javascript and act accordingly.

PHP / CI: Facebook Connect seems to use my site session instead of Facebook session

I've got a CodeIgniter project using the Facebook Connect "official" PHP implementation. For the most part it works fine, except for when a user first allows permissions. I've traced the problem deep into the provide facebook.php, the getSession() function:
public function getSession() {
if (!$this->sessionLoaded) {
$session = null;
$write_cookie = true;
// try loading session from signed_request in $_REQUEST
$signedRequest = $this->getSignedRequest();
if ($signedRequest) {
// sig is good, use the signedRequest
$session = $this->createSessionFromSignedRequest($signedRequest);
}
// try loading session from $_REQUEST
if (!$session && isset($_REQUEST['session'])) {
$session = json_decode(
get_magic_quotes_gpc()
? stripslashes($_REQUEST['session'])
: $_REQUEST['session'],
true
);
/* HERE IS WHERE IT GOES WRONG */
$session = $this->validateSessionObject($session);
}
My comment in the code is where things go wrong. The if block above gets evaluated successfully, but the code inside the json_decode() function parameter returns the string:
a:4:{s:10:"session_id";s:32:"********";s:10:"ip_address";s:13:"********";s:10:"user_agent";s:50:"Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2";s:13:"last_activity";i:1304286136;}edc0c222265e0a16c0f3fe8a96decf77
This looks like my site session, rather than the facebook session that it's trying to access (which I can see in the URL). Why is this happening? What can I do about it?
In case anyone else hits this particular snag, I'll post how I solved it:
Just change $_REQUEST to $_GET
My guess is that CodeIgniter somehow puts your session information into the $_REQUEST array... why this happens is beyond me, but it solved the problem for me. Hope it helps!

Resources