How can I set and get the session of the request from browser in Genie.jl?

Hello, I’m doing my Database course project using Genie as the back-end server, and I’m wondering how to set and save the session. And my efforts are as follows:

route("/api/login") do 
  uid = haskey(@params, :id) ? @params(:id) : ""
  password = haskey(@params, :password) ? @params(:password) : ""
  res = UsersController.checkLogin(uid, password, @params)
  println(@params[:SESSION])
  return res
end
  function checkLogin(uid, password, params)
    user = find(User, where("uid = ?", uid) + where("password = ?", password))
    ( (! haskey(params, Genie.PARAMS_SESSION_KEY) || params[Genie.PARAMS_SESSION_KEY] === nothing) ) &&
    (Sessions.start(params[:REQUEST], params[:RESPONSE], params))

    sess = params[:SESSION]
    if length(user) != 0
      return Dict("code" => 1, "msg" => "error!") |> json
    else
      Genie.Sessions.set!(sess, :uid, uid)
      # println(params[:SESSION], "\n\n\n", params)
      return Dict("code" => 0, "msg" => "success!") |> json
    end
  end

And I can print the @params[:SESSION] in the route.
However, when the browser makes a new request and I want to capture the user name in session, error occures that the @params does not have the key.
And I wonder how to use that properly. And in django framework, I know that I can simply use request.session['uid'] = 'someid' and get the session in the same way.
BTW, I notice that the Genie.Sessions.session function has some bugs that when the parameter does not have a :SESSION key, it will reture a HTTP.Request rather than a Session object:

function start(req::HTTP.Request, res::HTTP.Response, params::Dict{Symbol,Any} = Dict{Symbol,Any}(); options::Dict{String,String} = Dict{String,String}()) :: Tuple{HTTP.Request,HTTP.Response,Dict{Symbol,Any}}

function session(params::Dict{Symbol,Any}) :: Sessions.Session
  ( (! haskey(params, Genie.PARAMS_SESSION_KEY) || params[Genie.PARAMS_SESSION_KEY] === nothing) ) &&
      (params[Genie.PARAMS_SESSION_KEY] = Sessions.start(params[Genie.PARAMS_REQUEST_KEY], params[Genie.PARAMS_RESPONSE_KEY])[1])

  params[Genie.PARAMS_SESSION_KEY]
end

@AquaIndigo

  1. This test should explain it pretty well:
    Genie.jl/tests_Sessions.jl at master · GenieFramework/Genie.jl · GitHub

  2. It looks like you’re setting up user authentication so I suggest trying the GenieAuthentication plugin: GitHub - GenieFramework/GenieAuthentication.jl: Authentication plugin for Genie framework

1 Like

I’m so glad that I added Sessions.init() and the Sessions.session worked well.

However, the problem that I cannot get the session in the next request is still bothering me:

route("/ticket/all") do
  sess = Sessions.session(@params)
  println(sess)
  TicketsController.allTickets()
end

where

Genie.Sessions.Session("70c3a9c2bf659c250b8ad0e3cdba9acd81aa5be1a12be4701e389f957c3ad0d5", Dict{Symbol, Any}())

was displayed and I notice that it had a new name.

Thanks for the update @AquaIndigo - so basically a new session is generated with each request? Do you have the sessions/ folder? Are sessions being created there (you should see files named as the session id).

Do you get any errors and warnings in the REPL?

What’s the output of pkg> status?

Yes, when I made a new request in the browser and a new file in the session/ directory. And each route seems to generate one new session.

(DbTicket) pkg> st
Project DbTicket v0.1.0
Status `~/codes/JuliaProjects/dbTicket/Project.toml`
  [c43c736e] Genie v1.10.0
  [e6f89c97] LoggingExtras v0.4.2
  [739be429] MbedTLS v1.0.3
  [340e8cb6] SearchLight v0.21.1
  [1297d576] SearchLightMySQL v0.5.0
  [ade2ca70] Dates
  [56ddb016] Logging

And there were no warnings or errors.

@AquaIndigo as discussed on Genie’s Gitter, today’s v1.11 release should address the session problem in webkit based browsers. Please let me know how it works.

Thanks so much and the latest version works for me!