So it's time to move on to Sessions, and before we jump into actually writing some code, we should
talk about what sessions are.
You may know, but it will give it a brief overview in any case.
So when I'm on a Web browser, if I go to a site WWOR, I don't know, CNN dot com doesn't matter.
I hit this Web page, and what I've done is I've sent a request to some server out on the Internet somewhere
saying, hey, I would like to get the homepage for CNN dot com.
And at the moment I'm making that request.
The Web server knows certain things about me.
It knows my IP address.
I've sent in my preferred language.
Probably I've sent in all kinds of things, all part of the request.
So the web for Web server takes the request, assembles the response and sends back a fully formatted
Web page consisting of text and images, maybe links to videos, whatever it may be.
And the instant it finishes sending me that information, it forgets about me.
It doesn't know anything else about me.
I'm gone as far as I'm concerned.
If I click on a link here, if I click on whatever this is about.
Jeffrey Epstein, as far as the Web server is concerned, I'm an entirely new person and it knows nothing
about my previous request.
So that's not a problem.
If you're serving or surfing Web Web pages and you don't need the site, doesn't need to know anything
about you, it is a problem for things like user authentication.
How do how does the Web server, which is stateless and doesn't know anything about me between visits,
how does it know whether I'm logged in or not?
How does it know anything that needs to persist between page requests?
Well, this is where sessions come in and the sessions are something that we need to set up in our application.
Now, there's a number of ways of implementing this.
The easiest way is to choose a session package that you think suits your needs.
And there are many to choose from.
Gorilla, a package called Gorilla Sessions.
There are many to choose from.
I'm going to use a particular one that I like very much.
So the one that I'm going to use is right here at GitHub Dotcom Alex Edwards legacy s.
So I'm going to install that package before I do anything else.
So I scroll down, I finally installation string, copy it, go back to my idy.
If I have my application running, I stop it and then I say go get or I said pace the whole thing in
there, go get GitHub, dotcom and so forth.
Hit return.
It should install it.
I can verify that by looking at go mod.
There it is, it's all installed and now I can start to use it.
Now when you're using a session, regardless as to what package you're using, you almost certainly
have to initialize it in some way, shape or form.
And the way that we do that is right here in our main file.
So I can maybe just after I declare my app config and before I go get my template cache, doesn't matter
where I put it, but I'm going to put it here and I'm going to simply say create a variable called Session
Now session.
I'm going to sign it right now, but I'm going to change that in a minute.
Session is from the package.
We've just installed a series and he gives his examples here where everything we used to call that is
actually calling S.A.S..
So C.
S dot, you and I better it imported it good as new.
And then I need to say I don't need to, but I'm going to.
How long do I want my sessions to live, for example.
So if I look at that variable session I just created, it has a bunch of functions that I can use and
one of the ones that I want to use is actually called Lifetime.
So F lifetime.
And that's going to be equal to a particular value.
And the I want it to last for twenty four hours so I can just say twenty four times time, which is
a built in go package dot power.
And now the sessions that are created will last for twenty four hours which is long enough.
You might want to go for thirty minutes if it's highly secure and you want people logged out as soon
as possible.
But twenty four hours is suitable for our purpose so I'll leave it there right now.
Also I'm using the default session package.
If I go back up here and look, you can see that it actually has a bunch of different stores.
So by default uses cookies, it just uses cookies to store our sessions.
And that's all we're going to do right now.
We may look at storing them in Rattus or something else later on, but there are many different stores
that he has.
Badger is a built in database that you can put right into your go application and it will store all
the sessions there.
Boult is this a similar thing?
Bolton Badger serve the same purpose.
In fact, one is based on the other.
You can store the memory store, you can store them in a minuscule database of Postgres database, retests
key value store or a school database equal like three database.
So we could do all of that.
But we're not going to right now.
We're just going to go with the defaults.
So since we're storing and cookies.
And since all sessions use cookies in one form or another, we need to actually set some parameters
for that cookie session cookie, which is built into the package we want to say processed should the
cookies persist after the browser window is closed by the end user.
I'm going to say true if you want the sessions to disappear.
The moment that someone closes the browser window or quits the browser, you set that default and then
the session will not persist the next time they open a window or fire up their web browser session cookie.
The same site, and this is a parameter that set in the cookie that tells it, you know, how strict
you want to be about what site this cookie applies to.
And we're going to go with a default that's built in to go called the same site, lax mode.
And there are other options there.
But this is sufficient for our purposes right now.
And finally, session cookie dot secure.
Well, this will insist that the cookies be encrypted and that the connection is from HTP X instead
of HTP.
I'm going to set that defaults in production.
You want that to be true and I'm going to set it defaults because we're hitting localhost 80 80 and
that is not an encrypted connection.
So we'll set it defaults right now.
It seems to me that's the second time we've had to do this sort of thing.
Session Cookie secure equals false.
Back in middleware, if you recall, we did the same thing here for the cookie that set for no surf.
We had to set that defaults as well.
Well, that seems really awkward.
Now, I have two things to remember when I when I have to go into production, I to make changes in
two places.
That seems to me to be really not a great idea.
So let's go back to our main function and think about how before we go any further we might be able
to set this variable everywhere it needs to be set.
Basically, the question I'm asking is a really simple one.
Am I running as a production server or am I running as a development server?
Well, it seems to me that one of the places we could actually change this might be by storing a value
in a config and the config value might be something as simple as in production and make that a loop.
Now, remember, we said the great thing about our app config being set up the way that it is, is that
I can store value in here and it's immediately available to every part of the application that uses
app config.
So I've now got a place to store that value.
Let's go set it.
And I might just say right here, change this to true well in production and there's even a better way
to do this.
But we'll get to that later on.
All I'm going to do is say app introduction equals false.
There now I can use this value anywhere that I need to.
So, for example, I can use it right here where it says and secure.
I can use it there.
Can I use it in my middleware?
Well, I want to put it right here.
Let's try again and see what happens.
No, I can't use that right there.
Why?
Because this is a function that has no access to that config, because back in main go my app config,
I declared here.
So it's limited to the scope of this main variable.
Now, since middleware is in the same package as main, it's in the main package.
All I really need to do is to cut this out of here and put it outside of the main function and now it's
available to middleware so I can store in there.
So I actually have a secure app in production.
Same site can be left with it, but I have my secure set here and I have my secure set here and I don't
need to worry about doing anything other than changing this fault's to a true before I compile the application
for production.
All right.
So I set up this session and one of the things that I said a moment ago was I probably I might at some
point need to use this session variable in my middleware, for example, which doesn't know anything
about it and has no access to the app variable.
So how can I actually make that work a little bit better?
Well, it's not too difficult.
What I'm going to do is come up here and declare a variable.
VAR session is going to be a pointer to Eckstut session manager.
OK, and that says it's not being used anywhere.
Well, it's not, because this variable, even though it has the same name as this variable, these
are two different things entirely.
And what this is actually called is variable shadowing and it's a really difficult problem to fix,
to define so you can fix it when it happens to your code.
So you need to be conscious of this.
This variable and this variable are not the same to make them the same.
All I have to do is that now I'm referring to a variable that exists outside of the scope and is available
to the entire main package.
So I've created that variable session and I've set its necessary parameters.
Where am I going to use this session?
Where is the most likely place that I'm ever going to have to get information from the session?
Well, the most likely place is almost certainly handlers.
Here is where I need to get access to that session.
But because Handler's is its own package right here, this is on package handlers and that session variable
session exists in the main package.
Never the two shall meet.
I need to get that session over to handlers and to anywhere else.
I might possibly have to use it.
So, again, where is the best way to place to put this?
Let's put it in config.
Go now, remember when I declared this variable, it's a type X session manager, so let's go back to
our config and create another field, another member to this.
And it's going to be called session and it has to have a capital letter.
So it's visible and it is of type star excession manager, a point or two in succession manager.
OK, so now that now we have a place to store our session back in May not go.
Now, once I have declared this session, all I have to do is say Apte session equals session.
And now if I need to, in my middleware, have access to that session, I can do it.
So my middleware in my handlers, let's say I go down to one of my handlers here and say Apte session,
sorry, Emdur app session.
You see, I have access to it and I can do all the things that I need to do from it so I can get a value
from the session or I can put a value into the session.
But we're not doing that yet, so I'll delete it.
I'm just demonstrating that in fact I now have access to that session variable stored in the application
confect.
So I've created this session so far.
All right.
Before we go any further, let's make sure everything compiles, even though I'm not using that session.
Let's try running our application.
It compiles perfect, so I come back over here and maybe reload the homepage and go to the about page,
perfect.
OK, so is that all I need to do?
Do I need to actually, just now that I've got the section variable and I can use it in my handlers
and I can use it in my main package and I could even actually use it in my middleware because middleware
is in the same package as Main and the session is declared at the package level.
I seems like I've got everything I need to start using sessions.
Well, not quite.
There is one more thing I need to worry about, because Web servers by their very nature are not state
aware.
I need to add some middleware that tells this web server and a Web web application is a web server that
it should remember state using sessions.
Unfortunately, it's really easy to use.
All I have to do is come in here and create some new middleware.
So I'm in my middleware.
Com package and I'm going to create a new function func and I'll call it session load.
All that does is load the session and like all middleware, it needs to take a parameter next and it
has to be at HTP Handler.
Right there, and it has to return an HDB handler.
And inside the function definition, what I do is really quite straightforward return session, dot
load and save and pass it next.
So all this does, we can go look at the source code for this if you want to.
All it does is it provides middleware, which automatically loads and saves session data for the current
request and communicates the session token to and from the client in a cookie.
That's it.
So now I've got this middleware, but it's not being used.
So let's go back to our roots and use it mixed up.
Use and paste such and save and load.
I'm actually that's fine.
Is now I have access to the sessions so if I quit out of the application a compiler it should compile
again and it does.
I'm going to go back to my middleware and give these things comments like they're supposed to.
Session load loads and saves the session on every request.
No, sir.
See us RF protection to all post requests.
OK, and this one, I, I'd left it there as a reference, but I don't need it anymore.
So it's going away.
So now I have everything I need to start using sessions.
I've initialize my session in the main function.
I've started in my configuration, my application wide configuration.
I've added the necessary middleware to save and load them.
We should be good to go.
So in the next lecture, let's try playing with Sessions and see how it might all work.
See then.