session for authenticated user is not being set - php

(I'm aware that the following example isn't safe)
I have a basic authentication system where a user has to enter his credentials. When the entered credentials are correct I set in my laravel application a session, which indicates that he can perform authenticated requests to the api. I do that the following way:
public function authenticate(Request $request){
$data = array(
'name' => $request->input('UserName'),
'password' =>$request->input('Password'),
'email' => 'test#test.ch'
);
If(Auth::attempt($data)){
$request->session()->put('isAuthenticated',true);
$request->session()->save();
return "success";
}
return "wrong";
}
My middleware where I check if the user is allowed to make requests:
public function handle($request, Closure $next){
if(!empty($request->session()->get('isAuthenticated')) && $request->session()->get('isAuthenticated') === true){
return $next($request);
}
return redirect('/');
}
My routes:
Route::post('/login', 'UserController#authenticate');
Route::group(['middleware' =>['web','check_auth']], function (){
Route::get('/logs','LogController#getAllLogEntries');
Route::get('/logs/{id}','LogController#getLogEntryById');
});
My problem:
Whenever a user logs in with the right credentials the server returns "success" as response, but always directs me back to the base root ('/'). That makes me assume that the session doesn't get set. How can I fix this error?

Related

How can i fix "not logged in" error in laravel even after logging in?

Im making a gym app on laravel 9 as an api. The app will have a normal user and also an admin which has access to certain files that a normal user doesnt. For that i created a middleware but im facing a few problems there.
See even after i log in, when i try using a route protected by my isAdmin middleware, i get the error: Log in to gain access. This is the Login function:
public function login(Request $request)
{
$creds = $request->validate([
'email' => 'required|email|string|exists:users,email',
'password' => ['required']
]);
if (!Auth::attempt($creds)) {
return response([ 'message' => 'Provided email or password is incorrect' ], 422);
}
/** #var \App\Models\User $user */
$user = Auth::user();
Auth::login($user);
$token = $user->createToken('main')->plainTextToken;
return response(compact('user', 'token'))->header('Authorization', 'Bearer '.$token);
}
and then this is the middleware
public function handle(Request $request, Closure $next)
{
if (Auth::check()) {
$user = Auth::guard('auth')->user();
dd($user);
if ($user->role == 1) {
return $next($request);
} else{
return response(['msg'=>'You are not authorized for this route!']);
}
} else{
return response(['msg'=>'Log In to gain access!']);
}
return $next($request);
}
Im pretty sure the problem has to do with the token either not being sent or being stored properly, but i cant seem to find where the problem is. Also this is what im doing in Postman if that would help:
Login
Add Recipe (this is a route guarded by the middleware)
And also here are their headers respectively
Also i dont know if this is info that will help but i have to manually write the that bearer token for it to show up. (im a beginner so idk how it should be done)

Laravel 5 viaRemember() always false

I've read the laravel 5 documentation https://laravel.com/docs/5.3/authentication to see how i can implement a way to keep users logged in.
But somehow with the code below my function Auth::viaRemember() always returns false. Also after browser restart. However in my database remember_token is set and so is my cookie.
I'm a bit confused right now, can someone explain what probably is happening?
This function is called to login the user
public function doLogin()
{
// create our user data for the authentication
$userdata = array(
'email' => Input::get('email'),
'password' => Input::get('password')
);
// attempt to do the login
if (Auth::attempt($userdata, true)) {
return Redirect::to('aview');
// validation successful!
}
}
This function is called to check logged in user by Auth::viaRemember()
public function checkLogin()
{
if (Auth::viaRemember()) {
return Redirect::to('aview');
} else {
return view('toaview');
}
}
Additional routes file (just in case)
Route::group(['middleware' => ['web']], function () {
Route::get('login', 'UserController#checkLogin');
});

Laravel maintain a session through ajax login

How am I able to maintain or create a session through Ajax login. I have a Laravel installation not that much different from a basic make:auth installation.
I had to ovewrite some parts of the authcontroller to return json instead of redirects. Here's the login part:
/**
* Handle an authentication attempt.
*
* #return Response
*/
public function login(Request $request)
{
$this->validate($request, [
$this->loginUsername() => 'required',
'password' => 'required'
]);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $this->hasTooManyLoginAttempts($request)) {
// to many attempts
if ( $request->ajax() )
{
$this->response['code'] = 406;
$this->response['message'] = $this->sendLockoutResponse($request);
return response()->json($this->response);
}
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
$credentials['is_active'] = 1;
if (Auth::attempt($credentials, $request->has('remember'))) {
// succes
return $this->handleUserWasAuthenticated($request, $throttles);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
if ($throttles) {
$this->incrementLoginAttempts($request);
}
// error
if ( $request->ajax() )
{
$this->response['code'] = 406;
$this->response['message'] = $this->getFailedLoginMessage();
return response()->json($this->response);
}
return redirect()->back()
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors([
$this->loginUsername() => $this->getFailedLoginMessage()
]);
}
/**
* Handle an authenticated response.
*
* #return Response
*/
public function authenticated($request, $user)
{
if ( $request->ajax() )
{
$this->response['message'] = "success";
return response()->json($this->response);
}
else
{
return redirect()->intended($this->redirectPath());
}
}
Here are the routes used:
Route::group(['namespace' => 'Auth'], function() {
Route::post('/login', ['uses' => 'AuthController#login', 'as' => 'login']);
Route::post('/registreer', ['uses' => 'AuthController#postRegister', 'as' => 'register']);
Route::post('/reset', ['uses' => 'PasswordController#sendResetLinkEmail', 'as' => 'reset']);
});
I am working with Vue.js in the frontend which get the error and succes responses perfectly. Only after refreshing the browser i am not in a logged in state. How am I able to do this.
There's no session when you are working with AJAX / JSON REST APIs. Instead of sessions, REST APIs use tokens / some kind of authentication.
If you are building a REST API and using VueJS as the front end framework for a single page application, use the api middleware instead of the default web middleware.
Read more information about JSON Web Tokens here:
https://jwt.io/introduction/
You are basically creating a stateless application when you are using Ajax. The frontend side basically didnt need to know the state of the user, wether he is already login or not. So you didnt need any session.
What you need to do is get information from the server wether your user is authorized to get any resource on the server. This is basically Authenticating (the process to validate user credential that being sent to the server and then returning sort of id to the user) and Authorization the process to check wether the id is authorized to access the resource requested.
I guess i declared my question not properly because of the misunderstandings. However i did get it to work. The fix is to put middleware around the specific routes. Now I am to login trough a Ajax request.
Route::group(['middleware' => 'web'], function () {
...
});

I get Auth::user is null in Laravel

I create middleware for an admin role using the following code:
php artisan make:middleware AdminMiddleware
After that, I create a route for the login page:
Route::get('admin/login', ['middleware'=>'web','as'=>'admin.login','uses'=>'AdminController#loginView']);
Route::post('admin/login',['middleware'=>'web','as'=>'admin.login','uses'=>'AdminController#login']);
Route::group(['prefix'=>'admin','middleware' => ['auth.admin','web']], function()
{
Route::get('/', ['as'=>'admin.home','uses'=>'AdminController#index']);
Route::get('/home', ['as'=>'admin.home','uses'=>'AdminController#index']);
});
And the controller is
class AdminController extends Controller
{
//
function index(){
return 'welcome';
}
function loginView(){
return view('admin.login');
}
function login(Request $request){
$error = $this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:5',
]);
$email = $request->input('email');
$password = $request->input('password');
$remember = $request->input('remember');
if (Auth::attempt(['email' => $email, 'password' => $password,'type'=>'admin'], $remember)) {
// Authentication passed...
Auth::login(Auth::user(), $remember);
return redirect()->route('admin.home');
}
else{//('message', 'Login Failed')
return redirect()->route('admin.login')->withErrors($request->all(), "message")->withInput();
}
}
}
And in AdminMiddleware
public function handle($request, Closure $next)
{
var_dump(Auth::user());
if(!Auth::check()){
return redirect()->route('admin.login')->withErrors('You are not logged in');
}
elseif ($request->user()->type != 'admin'){
dd($request->user());
return redirect()->route('admin.login')->withErrors('You have not authority');
}
return $next($request);
}
The error is: I always get null for each $request->user() or Auth:user in AdminMiddleware.
You're passing the middleware to the route group in an incorrect order.
Right now you have this order ['auth.admin', 'web'] which means that the auth.admin middleware will be executed before the middleware from the web group, and since web contains the StartSession middleware, you won't have any session in auth.admin which is needed to get the authenticated user.
So simply switch the middleware order like so:
Route::group(['prefix'=>'admin','middleware' => ['web', 'auth.admin']], function () {
// now the session is set up in `web` and then you have it in `auth.admin`
});
In my case the actual problem was a blank line before the PHP starting tag.
I used following core PHP function to redirect instead of returning a view file from controller or instead of using Laravel redirect.
header('Location: /');
It printed the actual file which had a blank line. Removing this line fixed my problem.
There were thousands of files in my code base. My assumption was that I had tried different scripts to find such blank lines at start of any file and there was no such file as per those scripts results. I assumed there was no blank line in any of my files. But header('Location: /') proved that my assumption was not wrong, and I was working on the wrong lines.

User Auth not persisting within Laravel package

This is my first attempt at a laravel package and have run into an issue where Auth::attempt($credentials) works within my login controller, but upon redirection to a protected route or controller, the user is no longer authenticated. Below is my login controller method with the redirect to dashboard commented out.
public function attempt(Request $request){
$email = strtolower(strip_tags(htmlspecialchars($request->input('email'))));
$password = strip_tags(htmlspecialchars($request->input('password')));
if (Auth::attempt(array('email' => $email, 'password' => $password)))
{
// Redirect to dashboard route
//return redirect()->intended('/admin');
if(Auth::check())
print_r(Auth::user());
}
}
A response to valid credentials prints out the correct user record and Auth::check returns true. But, when redirected to the admin controller, the user is not authenticated. Below is the admin controller method that should output the authenticated user, but only returns "not logged".
public function index()
{
if(Auth::check()) print_r(Auth::user());
else echo "not logged";
}
Both controllers use Auth;, their namespaces are consistent with vendor/package/pathToDir, db is setup correctly, and the encryption key has been set. Any ideas on what's going wrong? Thanks
Turns out the issue was with the new web middleware, moved all my routes that require session data in to the route group and everything works as normal.
Route::group(['middleware' => ['web']], function () {
Route::get("/login", ['uses'=>'SiteLogin#index']);
Route::post("/login", ['uses'=>'SiteLogin#attempt']);
Route::get("/logout", ['uses'=>'SiteLogin#logout']);
Route::group(['prefix' => 'admin', 'middleware' => 'auth'], function () {
Route::get('/', ['uses'=>'Admin#index']);
});
});
The default behavior of the method attempt is to not keep the user logged.
You should change it to:
if (Auth::attempt(array('email' => $email, 'password' => $password), false, true))
This way you will set remember as false and login as true.
Check more about this here: https://laravel.com/docs/5.2/authentication

Categories