Viewed   788 times

I'm trying to share a Session value with all views using AppServiceProvider class.

In the boot() function I said: view()->share('key', Session::get('key'));

But, the value is null. What can be the problem? In the Controller I'm setting it, it works fine. Even after removing the Session::put() line, the value is still in the session (obviously).

 Answers

2

In Laravel session is initialized in a middleware that is handled by this class:

IlluminateSessionMiddlewareStartSession::class

When the service providers are booted, this middleware has not been executed, because all the middlewares execute after the service providers boot phase

So, instead of sharing the variable from a service provider, you can create a middleware and share the session variable from there, or you can use a view composer with a callback in your service provider:

public function boot()
{
    view()->composer('*', function ($view) 
    {
        //this code will be executed when the view is composed, so session will be available
        $view->with('key', Session::get('key') );    
    });  
}

This will work, as the callback will be called before the views are composed, when the middleware has already been executed, so session will be availabe

In general, pay attention at your middleware's execution order: if you want to access the session from a middleware, that should execute after Laravel's StartSession::class middleware

Friday, October 21, 2022
5

You can't read session directly from a service provider: in Laravel the session is handled by StartSession middleware that executes after all the service providers boot phase

If you want to share a session variable with all view, you can use a view composer from your service provider:

public function boot()
{
    view()->composer('*', function ($view) 
    {
        $view->with('your_var', Session::get('var') );    
    });  
}

The callback passed as the second argument to the composer will be called when the view will be rendered, so the StartSession will be already executed at that point

Sunday, December 18, 2022
 
5

While your users are accessing via HTTPS, your CloudFlare configuration is passing those requests onto your server using HTTP. You have two options:

  1. Turn on CloudFlare's Full or Strict SSL. https://blog.cloudflare.com/origin-server-connection-security-with-universal-ssl/

  2. Set up your webserver to see the X-Forwarded-Proto header and tell PHP it's being accessed via HTTPS when that header's value is https. How to do this depends a bit on your webserver. In nginx, for example, I do this for Amazon's ELB (which sends the same headers):

map $http_x_forwarded_proto $is_https {
    default off;
    https on;
}

and then this in my FastCGI params file:

fastcgi_param  HTTPS              $is_https if_not_empty;

In Apache, I think you can do this if mod_setenvif is installed:

SetEnvIf x-forwarded-proto https HTTPS=on
Thursday, August 25, 2022
5

It wouldn't be an issue storing it in the session.

In the is_manager function in your User class, you could do something like the following...

public function is_manager()
{
    // Check if the session has been set first.
    if(Session::has('is_manager')) {
        return Session::get('is_manager');
    }

    // Do your necessary logic to determine if the user is a manager, ex...
    $is_manager = $this->roles()->where('name', '=', 'manager')->count() == 1;

    // Drop it in the session
    Session::put('is_manager', $is_manager);

    return $is_manager;
}

Keep in mind if your session driver is set to database, then this obviously isn't going to help.

Sunday, December 25, 2022
 
xsl
 
xsl
3

To follow on from what others have said. I tend to have two layers:

The core layer. This is within a DLL that is added to nearly all web app projects. In this I have a SessionVars class which does the grunt work for Session state getters/setters. It contains code like the following:

public class SessionVar
{
    static HttpSessionState Session
    {
        get
        {
            if (HttpContext.Current == null)
                throw new ApplicationException("No Http Context, No Session to Get!");

            return HttpContext.Current.Session;
        }
    }

    public static T Get<T>(string key)
    {
        if (Session[key] == null)
            return default(T);
        else
            return (T)Session[key];
    }

    public static void Set<T>(string key, T value)
    {
        Session[key] = value;
    }
}

Note the generics for getting any type.

I then also add Getters/Setters for specific types, especially string since I often prefer to work with string.Empty rather than null for variables presented to Users.

e.g:

public static string GetString(string key)
{
    string s = Get<string>(key);
    return s == null ? string.Empty : s;
}

public static void SetString(string key, string value)
{
    Set<string>(key, value);
}

And so on...

I then create wrappers to abstract that away and bring it up to the application model. For example, if we have customer details:

public class CustomerInfo
{
    public string Name
    {
        get
        {
            return SessionVar.GetString("CustomerInfo_Name");
        }
        set
        {
            SessionVar.SetString("CustomerInfo_Name", value);
        }
    }
}

You get the idea right? :)

NOTE: Just had a thought when adding a comment to the accepted answer. Always ensure objects are serializable when storing them in Session when using a state server. It can be all too easy to try and save an object using the generics when on web farm and it go boom. I deploy on a web farm at work so added checks to my code in the core layer to see if the object is serializable, another benefit of encapsulating the Session Getters and Setters :)

Sunday, November 13, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :