How exactly is the session cookie generated?

I am using Guardian for authentication, and after a session is created I wanted to be able to use that session cookie for a JSON endpoint for my Chrome extension. So the idea was that whenever a user signed in, I’d send that session cookie to my Chrome extension and keep it in local storage so that I could use it as a bearer token when making API requests.

However I figured that I was wrong, and session cookie can not be used as a bearer token as it’s also encrypted again by Phoenix(or Plug? please correct me).

After that I decided to dig deeper to see how things work to understand better. I started with the sign_in/3 function from Guardian which basically puts the JWT into the plug_session as guardian_default_token (not sure though).

So in my Conn's private field I see:

:plug_session => %{
      "_csrf_token" => "Fc_F3bq30TQYFza7hsm4dhDW",
      "guardian_default_token" => "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJkZXJkaW5pX2dnIiwiZXhwIjoxNjM1MTA0MTE5LCJpYXQiOjE2MzI2ODQ5MTksImlzcyI6ImRlcmRpbmlfZ2ciLCJqdGkiOiI2NzkxMzZlYy0xN2Q3LTRmY2EtYjc4ZS00NTQ4MTdjNGZkN2QiLCJuYmYiOjE2MzI2ODQ5MTgsInN1YiI6IjIiLCJ0eXAiOiJhY2Nlc3MifQ.Rv4b8MXr2EuUPvUPmYmfFqIu_Bk8H2ZeCwMJqMi6X3ClPJVcXlOW6As1ErBI5-7r9zzcMmV4imMYnN4K-uUEVQ"
    },

After that I’ve inserted require IEX; IEX.pry() somewhere in session controller before creating the session to inspect the Conn. So, using put_session/3 I put "foo" => "bar" into plug_session into the private field of my Conn.

:plug_session => %{
      "_csrf_token" => "Fc_F3bq30TQYFza7hsm4dhDW",
      "foo" => "bar",
      "guardian_default_token" => "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJkZXJkaW5pX2dnIiwiZXhwIjoxNjM1MTA0MTE5LCJpYXQiOjE2MzI2ODQ5MTksImlzcyI6ImRlcmRpbmlfZ2ciLCJqdGkiOiI2NzkxMzZlYy0xN2Q3LTRmY2EtYjc4ZS00NTQ4MTdjNGZkN2QiLCJuYmYiOjE2MzI2ODQ5MTgsInN1YiI6IjIiLCJ0eXAiOiJhY2Nlc3MifQ.Rv4b8MXr2EuUPvUPmYmfFqIu_Bk8H2ZeCwMJqMi6X3ClPJVcXlOW6As1ErBI5-7r9zzcMmV4imMYnN4K-uUEVQ"
    }

and then I was expecting session cookie to change or a Set-Cookie header with an updated session cookie but I was wrong. So my questions are:

  • Where exactly is the session cookie created/encrypted? I’d like to read the source code.
  • After the sign_in/3 function of Guardian what other functions are called until we return a response? That I couldn’t figure out.
  • How would I be able to create a new session cookie by putting in arbitrary key, value pairs like I tried above? :bowing_man:
1 Like

The session is just a map, until you configure a session store (the default is the cookie store).

The cookie store is an implementation of the Plug.Session.Store behaviour and implements the encryption and serialization/deserialization of the session data.

It is Plug.Session that calls put_cookie/3 to set the cookie.

I think I got that right :slight_smile:

3 Likes

And then put_cookie/3 calls Plug.Conn.put_resp_cookie/4. By using that function directly, I was able to set another cookie.

Now what I wonder is, in the session cookie is there only guardian token encoded? Or can I put different stuff within that session cookie? If so, how? :smiley:

Sorry for the late reply by the way, and thank you for the answer!

You can put other items in the session with put_session/3 and those items will be added to whatever session store you have configured. The session is just a map until it is serialised, encrypted and signed before sending with the HTTP response.

1 Like

Oh now I can see that in action, I don’t know what I did wrong before and I thought it didn’t work.
After I use put_session/3 I can see the session cookie changing.

Thank you!