I am using DC User Plugin with activated "RememberMe" Cookie. If the session is expired and I reload a public page, it works fine (it gets the cookie and renews the session).
But if I reload a page (after session has expired) which is only allowed for logged-in users, it does not check the cookie and redirects me instead to the login page. But if I then click another (public) page and then go back to the user-only page - it works, too, without to have to login again.
So the RememberMe/Cookie Component itself seems to work fine.
My Code for the Auth check for the problematic user-only page is simple:
public function view() {
if (!$this->Auth->user()) {
$this->redirect('/users/login');
} else {
//do stuff
}
}
What do I have to add/change, so that it checks the User Cookie here, too, when the Session is expired? In the documentation of that Plugin I couldn't find that unfortunately.
Thank you so much for your help and sorry for my bad English.
Well I resolved by myself. Allthough I had added
$this->RememberMe->restoreLoginFromCookie();
to beforeFilter() function in Controller, the function always returned false, because the Cookie saves email+password, but Standard Auth expects username+password.
I added
public $components = array(
...
'Auth' => array(
'authenticate' => array(
'Form' => array(
'userModel' => 'User',
'fields' => array(
'username' => 'email',
'password' => 'password'
)
)
),
...
so it will check for the needed email field, and now it works.
Related
In this scenario, OurCustomAuth is currently returning an expected value of false, is reaching the appropriate else, but the users/error path keeps redirecting even though it's been made public and not requiring any authentication.
I've setup the new action:
C:\wamp\myapp\app>Console\cake AclExtras.AclExtras aco_update
Welcome to CakePHP v2.4.9 Console
---------------------------------------------------------------
App : app
Path: C:\wamp\myapp\app\
---------------------------------------------------------------
Created Aco node: controllers/Users/error
Aco Update Complete
In the UsersController, I've added the action to be made public:
public function beforeFilter() {
parent::beforeFilter ();
$this->Auth->allow ('logout', 'error');
}
In AppController, the Auth config:
public $components = array(
'Acl',
'Cookie',
'DebugKit.Toolbar', 'Session',
'Auth' => array(
'authenticate' => array('OurCustomAuth'),
'loginAction' => array('controller' => 'users', 'action' => 'view'),
'authError' => 'Did you really think you are allowed to see that?',
'authorize' => array('Actions' => array('actionPath' => 'controllers'))
)
);
...
public function beforeFilter() {
...
//Auto logging users in if they are not logged in
if (!AuthComponent::user('id')) {
if ($this->Auth->login()) {
//stuff here
} else {
$this->Session->setFlash(__('We could not authenticate you ...'));
return $this->redirect(array('controller' => 'Users', 'action' => 'error'));
}
}
...
}
The error I get in Firefox:
The page isn’t redirecting properly
Firefox has detected that the server is redirecting the request for
this address in a way that will never complete.
Update #1
$this->Auth->login() essentially grabs request headers, that in this case are intentionally wrong, which seems to redirect to the appropriate link. However, /users/error shouldn't cause a redirect as it's excluded from Authentication.
The problem is that you run your login code on every request, ie in the app controllers beforeFilter() method. So when that code redirects you to /users/error because you're not logged in, the code will run again for that controller/action, and redirect you again, and again, and again...
If you need to run this code for every request, then you'll have to check the allowed actions manually, ie the actions allowed via $this->Auth->allow(), and run your code only in case the current action isn't allowed. Check the code of AuthComponent::_isAllowed(), you can easily use that with minimal modifications:
$action = strtolower($this->request->params['action']);
if (!in_array($action, array_map('strtolower', $this->Auth->allowedActions))) {
//Auto logging users in if they are not logged in
if (!AuthComponent::user('id')) {
// ...
}
}
I am trying to integrate facebook authentication to my Cakephp 2.2.4 app and once the facebook authentication is done, I am trying to create the user and login the user manually, I see that though the below code is creating a auth session, i.e., $this->Auth->user() contains all the data , it is not logging the user into the app, i.e, I am not able to access other functions of the app
$user = $this->User->findById($user_id);
$this->Auth->login($user);
this is what I am using to manually login and the user saved does not contain a username and password
this is in my AppController.php
class AppController extends Controller {
public $components = array(
'Session',
'Auth'=>array(
'loginRedirect'=>array('controller'=>'Users','action'=>'dashboard'),
'logoutRedirect'=>array('controller'=>'Users','action'=>'login'),
'authError'=>'You can\'t access that page',
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'email')
),'Basic'),
'authorize'=>array('controller')
),
'RequestHandler'
);
public $helpers = array('Js' => array('Jquery'),'Html','Form');
public function isAuthorized($user){
return TRUE ;
}
public function beforeFilter(){
// $this->Auth->allow('index','view');
// $this->set('logged_in',$this->Auth->loggedIn());
// $this->set('current_user',$this->Auth->user());
}
}
Try:
$this->Auth->login($user['User']);
This was nothing to do with the cakephp app but the plugin which i was using for facebook, which did not post data
Maybe the Auth component still refer to username field for authentication instead of email. You can try change to username.
I am developing a Plugin that uses Facebook oAuth as an authentication object for Auth Component. If you want an already-built solution that uses server-side Facebook login, please check my website: http://marianofino.github.com/Facebook-Plugin-for-CakePHP/
I am moving from CakePHP 1.3 to CakePHP 2.2.2 and want to use Basic Http authentication for a simple admin area. I am just not able to make it work and I am thinking that I understood something wrong in the documentation.
From the documentation I understood I have to do something like
public $components = array(
'Auth' => array(
'authenticate' => array(
'Basic'
),
'authError' => 'You may not access this area.',
'authorize' => array('Controller')
)
);
I understand that further I need to extend the BaseAuthenticate Component to return valid user date but even with the above configuration I would expect that the browser's Http Access Dialog would open up in a popup window. But nothing like this happens, instead I am redirected to /users/login which does not exist. Why do I need a login view for Http Access? I am confused.
Add the Auth component to your controller (or to the AppController)
class ThingsController extends AppController {
var $components = array('Auth');
}
CakePHP requires a login action, so even if you use Basic authentication, where the HTTP agent is responsible for the UI to collect authentication details, you need to designate an action in some controller which will handle the login (in the Basic case, it will send the WWW-Authenticate: Basic header if the user is not authenticated yet).
You can set the AuthCompoment's $loginAction, but this defaults (and is advisable not to break conventions) to the login method in the UsersController. So, first create an empty template at View/Users/login.ctp, then add the following to your UsersController
class UsersController extends AppController {
public $components = array(
'Session',
'Auth' => array(
'authenticate' => array('Basic')
)
);
public function login() {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Not able to login');
}
}
public function logout() {
$this->redirect($this->Auth->logout());
}
}
I have an issue with cake's auth that I simply can't seem to get past (i've been debugging and trying different tutorials for the last two days). As far as I can see it should be very simple, the problem is whenever i try to login, it just refreshes the login page. I cannot for the life of me figure out why! My only conclusion is that there must be something (basic) which tutorials take for granted that I have missed.
Here are a couple of snippets:
users_controller.php
class UsersController extends AppController {
var $name = 'Users';
function beforeFiler() {
parent::beforeFilter();
}
function login() {
}
function logout() {
$this->Session->setFlash('You have successfully logged out.');
$this->redirect($this->Auth->logout());
}
}
app_controller.php
class AppController extends Controller {
var $helpers = array('Html','Form','Javascript');
var $components = array('Auth');
function beforeFilter() {
$this->Auth->loginAction = array('controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'contents', 'action' => 'index');
$this->Auth->logoutRedirect = array('controller' => 'contents', 'action' => 'view');
$this->Auth->loginError = 'Something went wrong';
$this->Auth->allow('register', 'view');
$this->Auth->authorize = 'controller';
$this->set('loggedIn', $this->Auth->user('id'));
}
function isAuthorized() {
return true;
}
}
login.ctp
<div class="midCol short">
<h3>Login</h3>
<div class="loginBox">
<?php e($form->create('User', array('controller'=>'users','action'=>'login')));?>
<?php
echo $this->Form->input('username');
echo $this->Form->input('password');
e($this->Form->end(array('label'=>'Login', 'class'=>'loginButton button png')));?>
</div>
</div>
Any help would be greatly appreciated, this has me tearing my hair out!
Just for documentation as I had difficulties finding an answer for CakePHP 2.x on the web. This stuff needs to be "correct" in order to use Form authentication:
The config needs to be right, e.g. in your UsersController (the fields config is really only required when names differ in the DB):
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array(
'username' => 'username',
'password' => 'password'
),
)
)
)
);
You have to use the Form Helper: Form->create adds a hidden input field ("post"), and the names of the input fields generated by Form->input() follow a convention that the Auth component expects.
User->login must not pass custom data to Auth->login(). The Auth component will take the auth data from the form (= request).
Thanks for the advice, but I ended up scrapping it and building again from scratch. Not exactly sure why it was originally breaking, probably not calling inbuilt functions with American English!
The Auth component will redirect to the page before you logged in. If that page was the login page that's where it'll redirect to.
When you're testing, it's likely that you're refreshing the login page, so on successful login that's where you're redirected to. You can check this by trying to perform an Auth protected action after logging in.
This gives me a lot of headaches as well - I think the current functionality of the component is a little clumsy in that respect.
I had the exact same problem and found that I had to restart mySQL service. Once it was restarted I stopped getting the login page being redirected. Hope that helps.
Gonna throw something in here. I was having an almost unresolveable problem with cakephp authentication. Ended up doing some debugging around it and found that during my database prep I had created a field for the password which was perfectly able to store normal size passwords... but.... when you start applying password hashing you need a lot more. My code was fine, but I had to add a bunch more space into the VARCHAR field for the password before I could log in. If you're having a problem with authentication - make sure your password field is adequately sized and not getting truncated like mine was. Took me a whole day to find that. DOH!
Correct me if i am wrong but must there not be code for redirection or something inside the function of login
function login() {
}
should it not be something like
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Invalid username or password, try again'));
}
}
I have created a feature to upload and download file in my site. But I want to validate the download feature. I want to allow a user to download file if user is already logged in to my site and given permission to download.
Help me. How to check whether session is present there or not?
I am uploading files in /app/webroot/documents/users/ path.
Download link generated is like this : http://localhost/my_project/documents/users/TGlnaHRob3VzZS5qcGcxMjc3ODIzMTAx.jpg
Thank you all.
The easiest way to deal with this is to use the AuthComponent for your authentication and the MediaView for handling the download prompt from a "download this file" link on the page.
An Example.
class SomeController extends AppController {
...
public $components = array(
'Auth' => array(
... auth settings ...
),
...
);
public function download( ){
$this->view = 'Media';
$this->set( array(
'id' => 'TGlnaHRob3VzZS5qcGcxMjc3ODIzMTAx.jpg',
'name' => 'TGlnaHRob3VzZS5qcGcxMjc3ODIzMTAx',
'download' => true,
'extension' => 'jpg',
'path' => join( DS, array(
APP, 'webroot', 'documents', 'users', ''
))
));
}
This assumes you have the download action as a restricted action with regards to the AuthComponent. If you have the download action allowed you can wrap the MediaView code in an Auth->user( ) check like so..
public function download( ){
if( $this->Auth->user( )){
$this->view = 'Media';
$this->set( array(
'id' => 'TGlnaHRob3VzZS5qcGcxMjc3ODIzMTAx.jpg',
'name' => 'TGlnaHRob3VzZS5qcGcxMjc3ODIzMTAx',
'download' => true,
'extension' => 'jpg',
'path' => join( DS, array(
APP, 'webroot', 'documents', 'users', ''
))
));
} else {
... do something else here ...
}
}
This just checks that Auth has a valid User object saved to the session. This should only occur when there is a User logged in.
A couple of notes:
I use a blank array entry at the end of the join( DS, array( 'path', 'parts', '' ) call to get the trailing slash required for the path. Do that however you want - I am partial to join myself when building repetitive strings or paths.
http://book.cakephp.org/view/489/Media-Views
http://book.cakephp.org/view/563/Setting-Auth-Component-Variables
I would probably set something up so you're not giving them a direct download link. I usually set up an AttachmentsController, with a download() method. Then you can run all the permissions checks you want (and keep stats on the files, etc.)
In that case you can have your controller check the session variable before enabling the download.
If you're using the Session component, you can check the user's status in your users action using something like this:
if($this->Session->read('Auth.User.id'))
{
//download file
}
How you serve your files is up to you though, but that session check should work inside whatever you use to serve the file, such as Travis Leleu's AttachmentsController.