Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

laravel_developer's avatar

manual authentication - session not persisting

I have another old-school PHP project inside of Laravel public directory. I have to use it for authentication for now and would like to start using Laravel for new development for this project. I need to authenticate into Laravel while authenticating into the PHP project. I tried to use Sanctum and send API commands to Laravel and then process authenticating manually:

Auth::loginUsingId($user->user_uuid);

I learned that Sanctum does not support this function, so I switched to web routes and tried to do the same. I was able to get authenticated and confirmed with Auth::check() function.

Unfortunately, when I go to any other page created by Laravel and run the same command, it returns FALSE, indicating that I'm no longer authenticated.

I tried to collect bits and pieces of why the session is not preserved from posts online and tried many things; however, I can't seem to figure it out still. I found an old post that seems to have this dame issue (can't post links) -authenticated-sessions-not-persisting - It suggested using web middleware. After reading the documentation, I learned that it automatically applies to web routes by default. Here is my route right now:

Route::post('/users/manual_auth', [UsersController::class, 'manual_auth'])->name('manual_auth')->withoutMiddleware([VerifyCsrfToken::class]);

Please, help me figure out how to make this work.

0 likes
22 replies
Sofia's avatar

I've tried to do something similar (have one application automatically authenticate a user into another), but by setting an encrypted cookie on the browser that was then decrypted by the Laravel application. It's hard to tell what you're trying to do without seeing more code, but perhaps there's a security issue with it and it's not setting/retrieving the session as you may expect.

laravel_developer's avatar

There is not much code besides what I posted. Here is where I try to authenticate and check

    public function manual_auth(Request $request)
    {

        $fields = $request->validate ([
            'user_email' => 'required|string|email',
            'password' => 'required'
        ]);

        $user= User::where('user_email', $request->user_email)->first();

        //Auth::guard('web')->login($user);

        if (!$user || !password_verify($request->password, $user->password)){
            return $this->sendError('Athentication failed.',[],401);
        }

        Auth::loginUsingId($user->user_uuid);

        if (Auth::check()) {
            return $this->sendResponse([
                'username' => $user->user_email,
                'user' => Auth::user(),
                ], 
                'User authenticated successfully.',
                200
            );
        } else {
            return $this->sendError('Athentication failed.',[],401);
        }
    }

I get 200 OK that the user is authenticated. Then I have a second route to just an empty Users page.

Route::get('/users', [App\Http\Controllers\UsersController::class, 'index'])->name('users');

I run the following code for this page.

    public function index()
    {

        if (Auth::check()) {
            return ("Users");
        } else {
            return ("No session");
        }
    }

Every single time I get No Session printed out, suggesting that the user is no longer authenticated

Snapey's avatar

You need to consider that when you authenticate the user, they must a) receive a session cookie b) present this cookie on every request in order to be paired up with the session and be authenticated.

If you are calling some code in laravel and then returning to the legacy app, you probably are not allowing the response to be sent correctly to the client. ?

laravel_developer's avatar

@Snapey I believe you are correct. I send the API call using Guzzle PHP from the legacy app to Laravel and then return to the legacy app. What do I need to do to properly receive the Cookie and then have it ready for opening other Laravel pages? The way I want it to work is where the legacy app is handling 90% of the app for now and only some pages that are newly added are processed by Laravel. I will eventually rewrite the code to sunset the legacy app but in the meantime, I need this functionality.

Snapey's avatar

@laravel_developer how are you going to route to the laravel app? will there be some routes that go direct or will you wrap them in the legacy app request?

laravel_developer's avatar

@Snapey Some pages will be served by Laravel, and some pages will be served by the legacy app. I tested that functionality, and it seemed to work fine until I hit the issue with authentication. There will be links on pages directing users between the two apps. The front end will look identical, so users won't know they are in a different app. That's why it's so crucial for me to be able to log in to both apps at the same time.

I've spent a week trying to approach this problem from different angles. If you have a better idea of how to accomplish this please, let me know. I would appreciate it.

laravel_developer's avatar

Update on this. After studying the records created in the database session table, I learned that sessions are appropriately created and stored. However, when I try to access a new page from the browser, it creates a new session. I suppose it's because the IP address is different, and it doesn't recognize a previously logged-in user.

Session authentication will not work for my project. I will research cookies for @sofia suggestion

Snapey's avatar

@laravel_developer no its because Laravel app does not receive the cookie, and it does not get the cookie because you didn't allow it to be sent to the client

ikarisroy's avatar

I learned that sessions are appropriately created and stored.

Sofia's avatar

@laravel_developer - Using cookies, we still ultimately use the web guard when a page is loaded. The only difference is that if there's no authenticated session on a page load, we have a different guard that checks for a cookie and creates an authenticated session if a valid cookie exists. Subsequent requests in the same session will not need to recheck the cookie every time. This is just a way to circumvent the login screen when accessing the app from another trusted app with the user already logged in - different from what you're trying to do.

Anyway, @snapey is probably right in that it has to do with the client not receiving the session cookie. Your Laravel route that authenticates is returning to your legacy app vs. the browser. You're using it like an API, which would typically need to authenticate on every call. Does your Laravel app serve views? Or API only?

laravel_developer's avatar

@Sofia Actually, it's no different at all. The user logs in to the legacy app, and it's trusted. So I don't want to have to log in again when the Laravel page is served. I might be over-engineering here, and that's why I wanted to ask the community what the best practices are. Laravel will serve some project pages, and the legacy app will serve the rest. This is a transitional state until I get all the pages coded with Laravel. Example:

// user logs in to the legacy app by going to the login page
Https://siteurl.com/logn.php

//user opens a Product page served by the legacy app 
https://siteurl.com/product.php

//user opens a Service new page built with Laravel
https://siteurl.com/service/show

I can already open all of these pages, and the proper engine appropriately serves them. The issue is the authentication part. I want to authenticate to Laravel while logging in to the legacy app. What is the best way to accomplish this?

I understand that part of the issue is that when I log in to the legacy app, I get redirected to the legacy app dashboard. This is why the cookie is not getting appropriately saved if I understand @snapey 's explanation. Is there any way around this?

Sofia's avatar

@laravel_developer I think the difference is that you’re going back and forth between your legacy and Laravel app. I’m just sending the user off to a different app. I authenticate during a regular page request, so the response comes back to the browser, but I think in your case it’s going back to your legacy app.

I’m still not understanding at what stage you’re authenticating your Laravel app. Can you give a play by play of requests/responses? Do you have a demo or dev site I can look at?

laravel_developer's avatar

@sofia I don't have a good demo website, as this is still in its infancy. The flow is the following:

I open https://siteurl.com and Laravel gets me redirected to the legacy app login page by a simple redirect:

header("Location: /legacy_index.php");

I'm logging in to the legacy app on that page, and while the form is getting submitted and the app checks credentials, I added some code to send a request to Laravel to sign in using the provided username and password. First, I tried an API request, and then I tried a web request. Laravel then does its part authenticating the user (manual_auth function I posted above), and when done, it returns 200 OK, and control returns to the legacy app. At that point, it finishes whatever else it may be doing and opens a dashboard. The dashboard will have links that will open some Laravel pages, but that's not built yet. Instead, I manually navigate to the https://siteurl.com/users page (code is also posted above) and, unfortunately, get a response that the user is unauthorized.

If you still like to see a demo, I can create something, but hopefully, this is clear enough. And again, if this is not the correct workflow I should be using, please let me know what I need to change to make this work.

Sofia's avatar

when done, it returns 200 OK, and control returns to the legacy app.

I think this is the problem, and also what I think @snapey was saying. Please re-read his response....I can't say it any better.

Try authenticating when you load a Laravel page for the first time, vs. making a special request for it. That way the response will come back to the browser and save the session cookie, which will be available for any subsequent request to your Laravel app. But you need to let the Laravel app know when a request is coming from someone that's logged in to your legacy app (vs. someone unauthenticated making a request) and this is where my initial suggestion with an encrypted cookie comes in.

laravel_developer's avatar

@Sofia I changed the code to show a Laravel page after authentication for test purposes. But it's not working still. Here is the Route:

Route::post('/users/manual_auth', [UsersController::class, 'manual_auth'])->name('manual_auth')->withoutMiddleware([VerifyCsrfToken::class]);

Here is the Controler Function:

    public function manual_auth(Request $request)
    {

        $fields = $request->validate ([
            'user_email' => 'required|string|email',
            'password' => 'required'
        ]);

        $user= User::where('user_email', $request->user_email)->first();
        if (!$user || !password_verify($request->password, $user->password)){
            return $this->sendError('Athentication failed.',[],401);
        }
        Auth::loginUsingId($user->user_uuid);

        if (Auth::check()) {
            return view('test');
        } else {
            return $this->sendError('Athentication failed.',[],401);
        }
    }

Here is the view I added. It's a simple page.

<!doctype html>

<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <title>A Basic HTML5 Template</title>
  <meta name="description" content="A simple HTML5 Template for new projects.">
  <meta name="author" content="SitePoint">

  <meta property="og:title" content="A Basic HTML5 Template">
  <meta property="og:type" content="website">
  <meta property="og:url" content="https://www.sitepoint.com/a-basic-html5-template/">
  <meta property="og:description" content="A simple HTML5 Template for new projects.">
  <meta property="og:image" content="image.png">

  <link rel="icon" href="/favicon.ico">
  <link rel="icon" href="/favicon.svg" type="image/svg+xml">
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">

  <link rel="stylesheet" href="css/styles.css?v=1.0">

</head>

<body>
  GOT TO THE VIEW.
</body>
</html>

The process is the same. I use the legacy app to authenticate the send a post request to Laravel. I see the Test page open, which means that Auth::check() function succeeded. I don't see a Cookie generated in the Chrome browser, and when I navigate to https://siteurl.com/users, I get a response that I'm not authenticated.

Interestingly enough, I see Cookies finally generated after I open that page.

What is the issue still?

laravel_developer's avatar

@Sofia, for the sake of testing, I'm not returning the view to my legacy app. I gathered that it breaks cookie generation from the previous posts. I'm researching further, and I think the issue is how I send my post request. I went with GuzzleHTTP, and I suspect it might receive the cookie back but not pass it to the browser. So when I open the next page using the browser, it doesn't know about that cookie. I believe there is an issue with this logic, and I might've gone the wrong path sending the post request using GuzzlePHP or missing some vital detail.

Sofia's avatar

The process is the same. I use the legacy app to authenticate the send a post request to Laravel.

@laravel_developer - It seems that the view is still going back to the legacy app and then you're sending it to the browser, so the cookie never makes it to the browser. Try re-directing from your legacy app to a normal page in your laravel app vs. sending a post request via Guzzle. Do the manual auth before you load your Laravel page (in the same controller, just for testing), to see if that works.

laravel_developer's avatar

@Sofia, Thank you for being so responsive. I could try that, but how do I securely send credentials while performing this redirect? I implemented this Guzzle just for that reason. Again I might be wrong, but it seemed like a safer way to do that.

Sofia's avatar

@laravel_developer That's where the encrypted cookie comes in (what I mentioned in my very first response). It's a way for your legacy app to communicate to the Laravel app that they have an authenticated user. Basically, if a valid cookie is found in the browser (set by your legacy app), then your Laravel can decrypt the cookie for any information that it might need and assume that it's ok to authenticate. Maybe there's a better and more secure way to do it, but that's what we do.

laravel_developer's avatar

@Sofia, do you have an example of the code that generated this cookie? I would appreciate it if you could share it. I've been banging my head for a month trying to figure this out.

Sofia's avatar

@laravel_developer Laravel has Cookie and Crypt facades that you can use. I can't share the code, but all it does is create a cookie with an encrypted payload, that the other app can decrypt (with a shared key) and use to determine if it will authenticate.

Please or to participate in this conversation.