Is there a way to make authentication into Codeigniter, only with username, not using a password?
Thank you in advance!
Of course. Hope you're not trying to store anything secure though. The terse Datamapper ORM solution would be something like the following. Adapt to Active Record if you need to.
The CodeIgniter
class Login extends CI_Controller{
function try_username(){
$p = $this->input->post();
if($p){
$u = new User();
$u->where('username', $p['username'])->get();
if($u->exists()){
$data = array("loggedin" => true "username" => $p['username']);
$this->session->set_userdata($data);
redirect('logged_in_controller');
}
}
}
}
Now your HTML:
<form action='login/try_username' method='post'>
<input type='text' name='username'/>
<input type='submit'/>
</form>
Well of course if you do not require security you could easily set your session based upon a single username. This is just as much possible in Codeigniter as in just PHP or other framework/language.
controller example:
function authenticate()
{
// check postdata
if ($this->input->post('username')):
if (!$this->auth_model->login($this->input->post('username',true))):
$this->session->set_flashdata('message', 'Bad username!');
else:
// go to user page or such...
endif;
endif;
redirect('login'); // take user back to login page
}
In above example I assume you have a model (auth_model) that checks database for username and sets login session for you. If user is not logged in then you get an error message and is sent back to login page...
you need only username = abc#gmail.com
public function login_ulogin($identity, $remember=FALSE)
{
$this->trigger_events('pre_login');
$this->trigger_events('extra_where');
$query = $this->db->select('username,group_id, email, id, password, active, last_login')
->where('username', $identity)
->from('users')
->get();
if ($query->num_rows() == 1)
{
$user = $query->row();
$password = TRUE;//$this->hash_password_db($user->id, $password);
if ($password === TRUE)
{
$this->set_session($user);
$this->update_last_login($user->id);
$this->clear_login_attempts($identity);
if ($remember && $this->config->item('remember_users', 'ion_auth'))
{
$this->remember_user($user->id);
}
$this->trigger_events(array('post_login', 'post_login_successful'));
$this->set_message('login_successful');
return TRUE;
}
}
//Hash something anyway, just to take up time
//$this->hash_password($password);
$this->increase_login_attempts($identity);
$this->trigger_events('post_login_unsuccessful');
$this->set_error('login_unsuccessful');
return FALSE;
}
Related
My environment is a laravel 5.8 with adldap2 in version 6.0.8 web app and an openLDAP directory.
After hours, I finally could authenticate my user against the openLDAP directory and also the database import into the users table works:
Id name username password remember_token created_at updated_at
King king $2y$10$YF9q7cYqjYnkl.We4Evwv.u/a2sddrfBA3pohgpS2vR... j4AOUHSlkHE3IQW7bsgF7pOIY8EAss6iukfnKhwi2lqXR0eTjE... NULL NULL
When I check the variable user in the function: attemptLogin -> $this->guard()->login($user, true); it is from the DB and seems to be fine. But still after I log in, I also get the message "Redirecting to http://localhost/home.", it returns to the login page and is still not logged in.
For LDAP authentication I followed mostly this example: https://jotaelesalinas.github.io/laravel-simple-ldap-auth/ even if it is a bit obsolete.
My attemptLogin function looks like this:
protected function attemptLogin(Request $request)
{
$username = Adldap::search()->users()->select('mail','uid','displayName')->findBy('cn', request()->get('username'));
$result = 1;
if($username){
if(Adldap::auth()->attempt($username->getdistinguishedName(), request()->get('password'))){
echo("success");
// Check group
$group = Adldap::search()->groups()->findOrFail('cio');
foreach ($group->getMemberNames() as $name) {
if($name === $username->getAccountName()){
echo("The user is a member of the group.");
$result = 0;
}
}
if ($result != 0){
$result = 2;
}
} else {
echo("Password wrong");
$result = 1;
}
} else {
echo(request()->get('username') . " not found");
$result = 1;
}
if($result == 0) {
// the user exists in the LDAP server, with the provided password
echo("Everything ok");
$user = \App\User::where($this->username(), $username->getAccountName())->first();
if (!$user) {
// the user doesn't exist in the local database, so we have to create one
$user = new \App\User();
$user->username = $username;
$user->password = '';
// you can skip this if there are no extra attributes to read from the LDAP server
// or you can move it below this if(!$user) block if you want to keep the user always
// in sync with the LDAP server
//dd($username->getDisplayName());
$sync_attrs = $this->retrieveSyncAttributes($username->getAccountName());
//dd($sync_attrs);
foreach ($sync_attrs as $field => $value) {
$user->$field = $value !== null ? $value : '';
}
}
$this->guard()->login($user, true);
return 0;
}
// the user doesn't exist in the LDAP server or the password is wrong
// log error
return $result;
}
Web.php
Route::get('login', 'Auth\LoginController#showLoginForm')->name('login');
Route::post('login', 'Auth\LoginController#login');
Route::post('logout', 'Auth\LoginController#logout')->name('logout');
Route::get('/home', 'HomeController#index')->name('home');
Has anyone an idea what I am missing? Or if you need more information, please tell me. It seems like the session is not stored.
Thanks in advance
Stephan
A small update after playing around some more hours. It seems like that Auth is after the successful login null. So tried different approaches I could find on the internet like changing the web.php routes or adding the protected $user variable to the LoginController.php but of course without any success.
I figured out that when I change the middleware from auth to web, I will get a session but the Auth::User() is still empty
Route::group(['middleware' => 'auth'], function () {
Route::get('/home', 'HomeController#index')->name('home');
});
After spending more and more hours, I finally found the solution in this thread: Laravel Auth:attempt() will not persist login
My issue was that I was using "echo's".
It cost me probably some days of my life
After I created a registration form with the fields: user, email, pass, cpass, I saved the user field in a session, so when I submit the form it should redirect me to the homepage displaying the message: hello + $this->session->userdata('user').
In my login form I have only the fields: email, pass and I want after submitting the form to be redirected aswell to my homepage displaying the same message but I don't know how to save the username in the session.How can I do that?
suppose you have a function in your model claass for checking user credentials.like-
function check_user($email, $pass) {
//select db column that you will need for future task
$this->db->select('id, user, email, pass);
$this->db->from('user_table');
$this->db->where('email', $email);
$this->db->where('pass', $pass);
$this->db->limit(1);
$query = $this->db->get();
if ($query->num_rows() == 1) {
return $query->result();
} else {
return false;
}
}
after returning in your controller function just put them in the session.like-
public function do_login(){
$result = $this->login_model->check_user($email, $pass);
//put them in the session
foreach($result as $row){
$this->session->set_userdata('user_id', $row->id);
$this->session->set_userdata('user', $row->user);
$this->session->set_userdata('email', $row->email);
//put more information as your need
}
}
please modify the code as your situation.
I'm facing problem while redirecting my user according to its type. how can do it here's my code please suggest how to do it.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class VerifyLogin extends CI_Controller {
function __construct()
{
parent::__construct();
}
function index()
{
$this->load->model('user','',TRUE);
//This method will have the credentials validation
$this->load->library('form_validation');
$this->load->library('session');
$this->form_validation->set_rules('username', 'Username','trim|required|xss_clean');
$this->form_validation->set_rules('password', 'Password'
'trim|required|xss_clean|callback_check_database');
if($this->form_validation->run() == FALSE)
{
//Field validation failed. User redirected to login page
validation_errors();
$this->load->view('error');
}
else
{
//Go to private area
basically here I want to redirect if user is admin then redirect to admin page else redirect to home. How can I do this ???
redirect('home', 'refresh');
}
}
function check_database($password)
{
//Field validation succeeded. Validate against database
$username = $this->input->post('username');
//query the database
$result = $this->user->login($username, $password);
if($result)
{
$sess_array = array();
foreach($result as $row)
{
$sess_array = array(
'id' => $row->id,
'username' => $row->username
);
$this->session->set_userdata('logged_in', $sess_array);
}
return TRUE;
}
else
{
$this->form_validation->set_message('check_database', 'Invalid username or password');
return false;
}
}
}
?>
The way I do this is by joining the user with a roles table. Each user is assigned to a role (such as salesperson, accounting manager, etc.). Each role has an optional home page to redirect to after login. If it's not set, it redirects to a default page.
Okay, well you say you have a login function so here are the basics. What Mike is saying is right and how I do it, but if you only have two types of users a roles solution is probably overkill. Personally I use the roles to populate a user menu, all users get the same menu, the options change depending on what portions of the site they're allowed to see.
For a basic admin/user though that's really not necessary. What you need to do is just redirect based on usergroup after login, so something similar to this.
$this->db->where(username, $username);
$this->db->where(password, $password);
$query = $this->db->get(users);
if($query->num_results() ==1)
{
$result = $query->result_array();
switch ($result['usergroup']) {
case '1':
redirect 'home';
break;
case '2':
redirect 'admin';
break;
default:
redirect 'home';
break;
}
}
As I said this is a basic solution that you can use for a few different roles, if you want to do anything more complicated investigate creating roles.
You'll also want to save the usergroup to the session and check it on admin pages, if the user isn't an admin redirect them away from the page.
wondering if anyone can guide me to what ive done wrong (or need to do) and think the problem is in my routes file. When the user is displayed the login form and for example they get their username wrong after submit the url displays as this: http://localhost:8888/codeigniter/login/login_validation. When the are successful and log into the admin area (which pulls news articles from the db) this url is still shown. I am wondering if there is a way to make it to http://localhost:8888/codeigniter/news. I have looked in my routes folder and i tried to use 'wildcards' and was unsuccessful. Here is my code for reference, any other info or files needed let me know! Thanks.
CONTROLLER:
class Login extends CI_Controller {
public function __construct() {
parent::__construct();
}
public function index() {
$this->load->view('login');
}
//Validate login area
public function login_validation() {
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'trim|required|xss_clean|callback_username_check');
$this->form_validation->set_rules('password', 'Password', 'required|xss_clean|callback_password_check');
if($this->form_validation->run() == FALSE) {
//Field validation failed. User redirected to login page
$this->index();
}else{
$this->load->model('user_model');
$query = $this->user_model->login_details();
// if the user's credentials validated...
if($query) {
$data = array(
'username' => $this->input->post('username'),
'is_logged_in' => true
);
$this->session->set_userdata($data);
redirect('news');
}else{
$data['error'] ="Invalid Username or Password";
$this->load->view('login',$data);
}
}
}
function logout() {
$this->session->sess_destroy();
$this->index();
}
}
login_details function from user_model.php
function login_details() {
$this->db->where('username', $this->input->post('username'));
$this->db->where('password', md5($this->input->post('password')));
$query = $this->db->get('login');
if($query->num_rows == 1){
return true;
}
}
If you're logging into any kind of system, you're going to need to store a session using CodeIgniter's Session class. Provided controllers/news.php exists, you can set the session and immediately just perform a redirect with redirect('news');. No need to $this->load->view() because this logic will be in news.php's index anyway and you'd be duplicating code.
I'm not sure what $this->user_model->login_details() is returning, but I'm assuming false or null because you say CodeIgniter is sending you back to the login view. Head into the login_details() function and make sure things are working properly (you might want to post it too). Also, post your routes.php file for us if you made changes just in case.
On a side note: Space is a valid password character, don't trim it or folks with leading or trailing space's in their passwords won't be able to get in ;)
I'm coding my first CI project and try to write a loginscript. Everything works almost fine, except that the session userdata is not available (even not if i check my cookies / sessions in Firefox).
I don't understand why the session userdata only are available after login, but if i load the same page again (not a refresh, but a new load) i would expect i still will be logged in, but i'm logged out ? Even if i try to read the session userdata it doesn't exists.
I simplified my script to an example version for stackoverflow. Who can tell me how this session issue can be solved?
Regards,
Guido
<?php
class Test extends CI_Controller
{
function index()
{
$logged_in = $this->is_logged_in();
if($logged_in) {
echo "You are logged in. <a href='test/logout'>Logout</a> | <a href='../'>Return to index</a>";
}
else {
echo "You are logged out";
echo form_open('test/check_login');
echo "Email: ".form_input('email', set_value('email'));
echo "Password: ".form_password('password', set_value('password'));
echo form_submit('submit','Login');
echo form_close();
}
}
function is_logged_in() // check if user has logged in
{
// AUTOLOAD SESSIONS HAS SET in autoload.php-config >> $autoload['libraries'] = arra y('database', 'session', 'email');
$is_logged_in = $this->session->userdata('is_logged_in');
if($is_logged_in) {
return TRUE;
}
else {
return FALSE;
}
}
function check_login()
{
$client_id = $this->validate();
if(is_numeric($client_id)) // if the user's credentials validated then user exists
{
$data = array(
'client_id' => $client_id,
'is_logged_in' => true
);
$this->session->set_userdata($data);
}
$this->index();
}
// normally we put this function in a model, but for this example we put it here.
function validate() // check if user exists in database
{
$this->db->where('email', $this->input->post('email'));
$this->db->where('password', md5($this->input->post('password')));
$query = $this->db->get('client_users'); // this is our user table
if($query->num_rows == 1) // user exists
{
$row = $query->row();
return $row->id_client;
}
else
{
return false;
}
}
function logout()
{
$this->session->sess_destroy(); // kill session, so user will be logged out.
redirect('/test');
}
}
?>
Your validate function's if statement should read:
if($query->num_rows() == 1) // user exists
You left out the () after num_rows.
Edit: After further review, that shouldn't matter. The only other thing I can tell is maybe your result is not equal to 1. Either the user isn't found or you're getting more than one result, both resulting in !== 1.