I have a form and I'm trying to login by using Laravels Auth method.
At the moment I have this snippet:
$input = Input::all();
$login = Auth::attempt([
'username' => $input['username'],
'password' => $input['password']
]);
if($login){
return "Logged in";
}
dd('problem');
But even after entering correct credentials I'm getting to see "problem"
in models/User.php I've changed my table name to tbl_login(like I have in the DB) and that is the only change I've made in it
and in my login model I have
class Login extends Eloquent {
protected $guarded = array();
protected $table = "tbl_login";
protected $primaryKey = "pk_loginID";
public static $rules = array();
}
I also checked this topic but didn't really help and I'm hoping that you guys can help me with this now.
Just as info and a sidenote: table name in Db = tbl_login
primary key field is pk_loginID
username field = username
password field = password
Did I forget something or did I do something wrong?
EDIT:
I've found the problem more specific, but not a solution for it. My password field in the DB has another name than the default password field that Laravel uses. How can I say to Laravel to use my custom password field?
I've found the solution
In the User model in the method getAuthPassword()
public function getAuthPassword()
{
return $this->attributes['passwordFieldinYourTable'];//change the 'passwordFieldinYourTable' with the name of your field in the table
}
That's it :)
You can't change it, but you probably can fix that by creating new mutators to the password field:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
...
public function getPasswordAttribute()
{
return $this->YourPasswordField;
}
public function setPasswordAttribute($password)
{
$this->YourPasswordField = $password;
}
}
Related
I'm working on a new project using CakePHP 3.0.
I'm using the authentication component and whenever a user logs in, I'm updating the value of the field visited.
UsersController:
public function login() {
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
$this->Users->setVisited($user['id']);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error('Your username or password is incorrect.');
}
}
UsersTable:
public function setVisited($id) {
$user = $this->findById($id)->first();
$user->visited = Time::now();
if($this->save($user)) {
return true;
}
return false;
}
Now, I would like to do this save without updating the value of the field modified. I've tried the approach used in previous versions of cake:
$user->modified = false;
It doesn't work though, throwing and error: Call to a member function format() on a non-object because datetime fields are now treated as objects I guess.
Any help would be greatly appreciated,
Paul
You have a couple ways of doing this. What you want is actually to avoid calling callbacks when saving the entity. For those cases you have updateAll
$this->updateAll(['visited' => Time::now()], ['id' => $id]);
You can also do the same as before, but you will need to disable the Timestamp behavior before saving:
$this->behaviors()->unload('Timestamp');
I would recommend using updateAll
I'm using CakeDC-Users plugin.
<?php
class Post extends AppModel {
public $useTable='posts';
public $belongsTo = array('User');
public $hasMany=array('Comment');
}
I had to use paginate:
$allposts=$this->paginate('Post');
I can get the user_id in this way:
foreach ($allposts as $post) {
debug($post['Post']['user_id']);
But i need the username not the user_id. How can i get username?
The containble feature of CakPHP hides all associated models by default: http://book.cakephp.org/2.0/en/core-libraries/behaviors/containable.html
If you want to add only one field of an associated Model you can use this syntax:
$allposts = $this->Post->find('all', array('contain' => 'User.username'));
or with paginate use this in your controller class: (http://book.cakephp.org/1.3/en/view/1232/Controller-Setup)
var $paginate = array('contain' => 'User.username');
Try the following to access it:
$post['User']['username'];
Try setting the recursive property to 2:
$this->Post->recursive = 2;
$allposts = $this->paginate('Post');
debug($allposts);
$allposts should contain every Post and it's belonging user.
See also: Cakephp pagination on recursive conditions
Does someone here know how to change the username before the Auth component reads the database?
The problem im having is im using mobile numbers as a login but i want to add the country code (if not present) when loggin in to my site
Any one have an idea on this?
Would be appreciated
If you are using CakePHP 2.0, you can manipulate the login form data as usual and then call $this->Auth->login(). Example:
// in your controller
public function login() {
if ($this->request->is('post')) {
$this->data['User']['username'] = $this->addCountryCode($this->data['User']['username']);
if ($this->Auth->login()) {
// login successful
} else {
// login not successful
}
}
}
you could always extend the Auth component and do whathever you want before the asking the database :)
Something like this...
function login($data = null,$public = false) {
$this->__setDefaults();
$this->_loggedIn = false;
if (empty($data)) {
$data = $this->data;
}
if (/** query the database to check/modify the data. You could use the identify() method of the AuthComponent **/) {
$this->Session->write($this->sessionKey, $user);
$this->_loggedIn = true;
}
return $this->_loggedIn;
}
If you extend the auth component, remember to always use this component instead of the default Auth class. (e.g. in the AppController, the build_acl, the initdb, the beforefilter on the controllers, etc.)
Hope this helps
I'm between a hard place and a rock with a CI problem. I have to dynamically connect to a DB with the username and password that users type. Those are their oracle usernames and passwords. So, with that information I have to do the connection to the DB and then keep it alibe for the different models and controllers within the application.
I have a login controller and a login view. I've disabled the database autoload from the database.php and config.php files.
Then, the login.php controller looks like this:
class Login extends CI_Controller {
public function index()
{
$this->output->enable_profiler(TRUE);
if (isset($_POST['ingresar'])){
$db['hostname'] = 'myhost';
$db['username'] = $_POST['usr'];
$db['password'] = $_POST['pwd'];
$db['database'] = 'DBname';
$db['dbdriver'] = 'oci8';
$db['dbprefix'] = '';
$db['pconnect'] = FALSE;
$db['db_debug'] = FALSE;
$db['cache_on'] = FALSE;
$db['cachedir'] = '';
$db['char_set'] = 'WE8ISO8859P1';
$db['dbcollat'] = '';
$db['swap_pre'] = '';
$db['autoinit'] = TRUE;
$db['stricton'] = FALSE;
$db['DB'] = $this->load->database($_SESSION, TRUE);
redirect('contactos', 'location');
}
else{
$this->load->view('/componentes/header');
$this->load->view('/componentes/menu_sin_login');
$this->load->view('/login/login');
$this->load->view('/componentes/footer');
}
}
When the controller redirects to the other controller "contactos" everything crashes because it doesn't recognize a database connection, on line 5, when trying to load a model.
class Contactos extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->model('Contactos_model');
$this->load->model('Componentes_model');.....
Any help you can provide would be really appreciated.
Regards,
V
In the context above $db is a local variable, which means it doesn't really do anything about the broader context of the script, and you're not storing it anywhere that it could be re-used.
To load the DB, you probably want to call:
// you may want to think about using an encrypted CI session instead?
$_SESSION['DB'] = $db;
then, in contactos, you would want:
class Contactos extends CI_Controller {
public function __construct()
{
parent::__construct();
$this->load->database( $_SESSION['DB'] );
// continue as above.
I would like to know how to deal with only ONE authentification process and "users" in multiple tables. I have 4 Users table: users, admins, artists, teamadmins which all have specific fields, but I would like all of these users to be able to connect via only one form on the homepage, and being redirected after that to their specific dashboards.
I think the redirections shouldn't be a problem, and some routes added should work, but I really don't know where to look/start to ake this all possible.
Cheers,
Nicolas.
EDIT: here's the final solution (thanks to deizel)
App::import('Component', 'Auth');
class SiteAuthComponent extends AuthComponent {
function identify($user = null, $conditions = null) {
$models = array('User', 'Admin', 'Artist');
foreach ($models as $model) {
$this->userModel = $model; // switch model
$this->params["data"][$model] = $this->params["data"]["User"]; // switch model in params/data too
$result = parent::identify($this->params["data"][$model], $conditions); // let cake do its thing
if ($result) {
return $result; // login success
}
}
return null; // login failure
}
}
CakePHP's AuthComponent only supports authentication against a single "User" model at a time. The model is chosen by setting the Auth::userModel property, but it only accepts a string and not an array of models.
You can switch the userModel on the fly with the following code, but this requires you to know in advance which model to switch to (eg. your users have to choose their account type from a dropdown):
public function beforeFilter() {
if (isset($this->data['User']['model'])) {
$this->Auth->userModel = $this->data['User']['model'];
}
}
You can likely extend the core AuthComponent to add the functionality you want by overwriting the AuthComponent::identify() method so it loops over and attempts authentication with each model:
App::import('Component', 'AuthComponent');
class AppAuthComponent extends AuthComponent {
function identify($user = null, $conditions = null) {
$models = array('User', 'Admin', 'Artist', 'TeamAdmin');
foreach ($models as $model) {
$this->userModel = $model; // switch model
$result = parent::identify($user, $conditions); // let cake do it's thing
if ($result) {
return $result; // login success
}
}
return null; // login failure
}
}
You will have to replace occurrences of Auth in your application with AppAuth to use your extended AuthComponent, unless you use this trick.
While annoying, I think the best solution is probably using Cake's built in ACL support (see http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/simple-acl-controlled-application.html).
If you do authentication the way you're talking about, you have to keep track of permissions in your controller code, checking to see what the userModel is. If you use an access control list, the permission tree will already exist in the database, which should simplify your code a great deal, and make it more modular.
It also means restructuring your data model to have a single users table and groups table instead of entity classes for each type of user.
I just went through the process of doing this myself... :(
this is also a possibility
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->authenticate = array(
AuthComponent::ALL => array('userModel' => 'AnotherModel'),
'Form',
'Basic'
);
}
Here is the final solution as suggested by deizel and modified by Nicolas:
App::import('Component', 'Auth');
class SiteAuthComponent extends AuthComponent {
function identify($user = null, $conditions = null) {
$models = array('User', 'Admin', 'Artist');
foreach ($models as $model) {
$this->userModel = $model; // switch model
$this->params["data"][$model] = $this->params["data"]["User"]; // switch model in params/data too
$result = parent::identify($this->params["data"][$model], $conditions); // let cake do its thing
if ($result) {
return $result; // login success
}
}
return null; // login failure
}
}