Session did't store values in live site - session

I am using laravel 4.2 and in my live site session did't store values. This way Auth::attemp(); working fine but Auth::check(); return always false. I already try to change domain name in session file. Thanks in advance
routes.php
Route::controller('/admin', 'adminIndex');
adminIndex.php
function getShow()
{
if (Auth::check())
{
return View::make('dashboard');
}
else
{
return Redirect::to('admin');
}
}
function postIndex()
{
$username = Input::get('username');
$password = Input::get('password');
if (Auth::attempt(array('username' => $username, 'password' => $password), true))
{
return Redirect::to("admin/show/");
}
else
{
return Redirect::to('admin')->with('message', 'Invalid User Name / Password.');
}
}

Auth function not working properly. it's approve your credential and destroy session. Update your laravel library and try.

Related

ADLDAP openLDAP authentication - Session not stored - returning to login page

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

Laravel Socialite Google login only with one domain

I have a Google+ login on my app with Laravel Socialite. When the login is done I have a callback to connect the user (I create her in database if necessary).
But I want to restrain the connection to only the company (email like "example#company.com", so only the email with "company.com").
Can I do it with Laravel Socialite ? I can make the verification manually in my callback but if Socialite can do it, it's better.
Thank you
My callback :
public function handleProviderCallback($provider){
$user = Socialite::driver($provider)->user();
if ($user) {
$local_user = User::whereEmail($user->getEmail())->first();
// If we don't have a user create a new user
if (!$local_user) {
$fragment = explode(' ', $user->getName());
$local_user = User::create([
'first_name' => isset($fragment[0]) ? $fragment[0] : '',
'last_name' => isset($fragment[1]) ? $fragment[1] : '',
'email' => $user->getEmail(),
'last_seen' => Carbon::now(),
'password' => ''
]);
$local_user->roles()->attach(Role::whereName('User')->first());
}
auth()->login($local_user);
}
return redirect($this->redirectTo);
}
You have a step by step guide for domain restriction.
In controller you need to specifiy these actions:
public function handleProviderCallback()
{
try {
$user = Socialite::driver('google')->user();
} catch (\Exception $e) {
return redirect('/login');
}
// only allow people with #company.com to login
if(explode("#", $user->email)[1] !== 'company.com'){
return redirect()->to('/');
}
// check if they're an existing user
$existingUser = User::where('email', $user->email)->first();
if($existingUser){
// log them in
auth()->login($existingUser, true);
} else {
// create a new user
$newUser = new User;
$newUser->name = $user->name;
$newUser->email = $user->email;
$newUser->google_id = $user->id;
$newUser->avatar = $user->avatar;
$newUser->avatar_original = $user->avatar_original;
$newUser->save();
auth()->login($newUser, true);
}
return redirect()->to('/home');
}
No, you can’t do it in Socialite itself because Socialite is just a mechanism of retrieving tokens from OAuth-compliant servers.
If you only want to accept users with a particular email suffix, then that’s business logic so something you should handle in your callback:
public function handleProviderCallback()
{
$user = Socialite::driver('google')->user();
if (Str::endsWith($user->getEmail(), '#example.com')) {
// Look up user and authenticate them
}
abort(400, 'User does not belong to organization');
}

Laravel issue with loginUsingId (Manual Authentication)

I am trying to implement a single signon on multiple domains. The concept is pretty simple i.e to send unique user tokens and then verify these tokens to find the user and then log him in.
Now after verifying the token and then grabbing the user, i do something like this
$loggedInUser = Auth::loginUsingId($user->id, true);
Now i have a custom middleware where it first checks for a logged in user, i.e
Auth::Check()
The above works fine for the first time. But on refresh Auth::check() is not validated. I have also tried using all different session drivers but still doesn't work.
I used a similar code on laravel 5.2, and it did work. But on laravel 5.3 its not validating on persistent requests.
Edit: Let me show you my Code
I have not modified AuthServiceProvider or any other guard. I do have the user model inside a directory but i have modified the path in auth.php.
Here is the route that domain1 points to:
http://domain2.com/{{$role}}/{{$route}}/singlesignon/{{$token}}
This is then picked up by verifySingleSignOn method inside the loginController which takes in the role, route that the user came in from other domain and the token. The user is then redirected to the same routes, but on domain2. Here i can successfully recieve the user id before manually logging in.
public function verifySingleSignOn($role, $route, $token)
{
// Fetch Single Signon
$userRepository = new UserRepository();
$user = $userRepository->checkForSingleSignOnToken($token, ['id']);
// Check if Token Exists
if (isset($user->id) && is_int($user->id) && $user->id != 0) {
// Manually Logging a user (Here is successfully recieve the user id)
$loggedInUser = Auth::loginUsingId($user->id);
if (!$loggedInUser) {
// If User not logged in, then Throw exception
throw new Exception('Single SignOn: User Cannot be Signed In');
}
$redirectTo = $role . '/' . $route;
return redirect($redirectTo);
} else {
return Auth::logout();
}
}
Then i have this GlobalAdminAuth middleware
// Check if logged in
if( Auth::Check() ){
$user = Auth::User();
// Check if user is active and is a globaladmin
if( !$user->isGlobalAdmin() || !$user->isActive() ){
return redirect()->guest('login');
}
}else{
return redirect()->guest('login');
}
return $next($request);
Now the first time everything works fine and the user moves through the middleware successfully . but the second time the else statement is triggered.
Edit: Code for checkForSingleSignOnToken
public function checkForSingleSignOnToken($token, $columns = array('*'))
{
return User::where('single_signon', $token)->first($columns);
}
try
Auth::login($user);
instead of
Auth::loginUsingId($user->id, true);
Cookies are restricted domain-wise. Your application on domain1.com wont be able to grab cookies set by domain2.com.
You should be customizing the guard to use some other mechanism than cookies. Maybe use a token in the query parameters.
add this to your protected $middleware array in app\Http\Kernel.php
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class
I think it has to do with an update in the framework
no using auth:check in middleware
using request->user() or auth::user()
Please review bellow code structure, i had made manual authentication
in laravel 5.0.
routes.php
Route::get('login_user_by_id/{id?}', ['as' => 'login_user_by_id', 'uses' => 'UsersController#login_user_by_id']);
Route::post('user_login_post_for_admin',['as'=>'user_login_post_for_admin','uses'=>'LoginController#user_login_post_for_admin']);
Route::get('user_logout', ['as' => 'user_logout', 'uses' => 'UsersController#user_logout']);
LoginController.php
public function user_login_post_for_admin(){
$this->set_email($_POST['email']);
$this->set_password($_POST['password']);
$this->set_login_requested_role(['Admin','Moderator']);
return $this->user_login_post();
}
public function user_login_post(){
$User = new User();
if(isset($this->email) && !empty($this->email)){
$User->set_email(trim($this->email));
$User->set_password(Hash::make(trim($this->password)));
$user_login_data = $User->check_email_password_for_login();
if(isset($user_login_data) && !empty($user_login_data)){
if (Hash::check(trim($this->password), $user_login_data[0]->password)) {
$response['user_id']=$user_login_data[0]->id;
$response['name']=$user_login_data[0]->name;
$response['surname']=$user_login_data[0]->surname;
$response['profile_picture']=$user_login_data[0]->profile_picture;
$response['SUCCESS']='True';
$response['MESSAGE']='Login Success.';
return Redirect::route('login_user_by_id',[$user_login_data[0]->id]);
}else{
Session::put('SUCCESS','FALSE');
Session::put('MESSAGE', 'Invalid Credential.');
return redirect()->back();
}
}else{
Session::put('SUCCESS','FALSE');
Session::put('MESSAGE', 'Invalid Credential.');
return redirect()->back();
}
}else{
Session::put('SUCCESS','FALSE');
Session::put('MESSAGE', 'Invalid Credential.');
return redirect()->back();
}
}
UsersController.php
public function login_user_by_id($id=''){
if(isset($_GET['id'])&&!empty($_GET['id'])){
$id = $_GET['id'];
}
$User = new User();
$Log=new Log();
$user_for_auth = $User->find($id);
Auth::login($user_for_auth, true);
$User->id=AUTH::user()->id;
$auth_user_role=$User->auth_user_role();
$rl_title=$auth_user_role[0]->rl_title;
return Redirect::route('admin_home');
}
public function user_logout(User $user){
$User=new User();
$login_user_id = AUTH::user()->id;
$User->id=AUTH::user()->id;
$auth_user_role=$User->auth_user_role();
$login_user_role=$auth_user_role[0]->rl_title;
$response['user_id']=$login_user_id;
$response['SUCCESS']='TRUE';
$response['MESSAGE']='Successfully Logout.';
Auth::logout();
return Redirect::route('admin_login');
}

how to pass session variable into view using laravel4

I want to pass logged in id into my view page.i got the id in the function of user_login_submits.
Actually i want to get the id in one more function in the same controller.
how to get the session id in controller..
Normally session put its enough i did like that.
Here is my code anyone can check and tel me what need to change here
Controller
public function user_login_submits()
{
$inputs = Input::all();
$uname = Input::get('username');
$password = Input::get('password');
$logincheck=Userlogin::login_checks($uname,$password);
if($logincheck == 1)
{
$id=Session::get('customer_id');
return Redirect::to('businessprio/create_news?p=1');
}
else if($logincheck == 0)
{
//echo "fail";
return Redirect::to('businessprio/create');
}
}
Model
public static function login_checks($uname,$password)
{
$check = DB::table('customer_login')
->where('username','=',$uname)
->where('password','=',$password)->get();
if($check)
{
//Session::put(['customer_id'=>'value']);
Session::put('customer_id', $check[0]->customer_id);
Session::put('username', $check[0]->username);
return 1;
}
else
{
return 0;
}
}
I won't pass it to model, instead i would do it in controller itself,
public function user_login_submits()
{
$uname = Input::get('username');
$password = Input::get('password');
$check = DB::table('customer_login')
->where('username','=',$uname)
->where('password','=',$password)->count();
if($check==1)
{
$id=Session::get('customer_id');
return Redirect::to('businessprio/create_news?p=1');
}
else
{
return Redirect::to('businessprio/create');
}
}
Recommendation :
But i would strongly recommend you to do it by Auth::attempt i.e., to follow the clean one
public function user_login_submits()
{
if (Auth::attempt(['email' => $userEmail, 'password' => $userPassword])) {
return Redirect::to('businessprio/create_news?p=1');
}
else
{
return Redirect::to('businessprio/create');
}
}
If you do so, then you can access the Default checking for authenticated user
Auth::check()
Get the Logged in user details by
Auth::user()->id
Auth::user()->username
Note : To use default Auth::attempt you should use the User Model too.

Laravel, log in user for one request

I am building a REST API with Laravel, and I have a filter that checks for a TOKEN:
Route::filter('api.auth', function() {
$token = Request::header('X-CSRF-Token') ? Request::header('X-CSRF-Token') : '';
if (empty($token)) {
return Response::json(
['message' => 'A valid API key is required!'],
401
);
};
$user = User::where('token', '=', $token);
if ($user->count()) {
$user = $user->first();
Auth::login($user);
} else {
return Response::json(
['message' => 'Your token has expired!'],
401
);
};
});
If everything is ok, the filter will log in the user with uth::login($user);
How can I log him for only 1 request?
Since this filter is going to be checked on every request, I think it would be better to log the user out each time.
I have seen this in Laravel's docs, not sure how to apply it:
if (Auth::once($credentials))
{
//
}
Could I have a callback in my response? where I could log the user out?
/*
Get all products.
*/
public function getProducts() {
$products = Auth::user()->products;
return Response::json($products, 200);
}
Any ideas?
If you haven't user's password use this:
if(Auth::onceUsingId($userId)) {
// do something here
}
If I correctly understand the question then I would say that, just replace following
Auth::login($user);
with this (To log the user in only for current request):
Auth::once(['email' => $user->email, 'password' => $user->password]);
If you log in a user only for once then you don't have to manually logo out the user, the user will be asked again for to log in on next request.

Resources