ire4ever1190 / mike

The new and improved mikero web framework
35 stars 1 forks source link

How to implement session cookies? #30

Closed AritraBanik08 closed 8 months ago

AritraBanik08 commented 8 months ago

How to implement session cookies?

ire4ever1190 commented 8 months ago

There isn't anything builtin since I didn't want to restrict how they are created.

Basic example using ponairi (For DB interaction) and anano (For ID generation) is

import pkg/[mike, ponairi, anano]
import std/options

# Just setting up the DB and a few helpers.
# Any ORM/DB solution can be used (Or even a table if you don't need persistance)

type
  Session = object
    id {.primary.}: string
    someData: string

proc initSession(data: string): Session =
  result.id = $genNanoID()
  result.someData = data

let db = newConn("someDB.sqlite")
db.create(Session)

# You'll want a route to create the session
"/session" -> post:
  let session = initSession("hello")
  db.insert(session)
  ctx &= initCookie("session", session.id)

# Then it can be used in other routes
"/someData" -> get(session: Cookie[string]):
  let foundSess = db.find(Session, sql"SELECT * FROM Session WHERE id = ?", session)
  ctx.send("Your data is " & foundSess.someData)

# You could also make a hook if you are using the session in multiple places
proc fromRequest(ctx: Context, name: string, T: typedesc[Session]): T =
  let sessionID = ctx.fromRequest("session", Cookie[string])
  let session = db.find(Option[Session], sql"SELECT * FROM Session WHERE id = ?", sessionID)
  if session.isSome():
    result = session.unsafeGet()
  else:
    raise newBadRequestError("Missing session cookie")

"/someOtherPlace" -> get(session: Session):
  ctx.send(session.someData)

Hope that helps! Feel free to ask any questions about the example

AritraBanik08 commented 8 months ago

The example you gave is great but I was asking if there is a way to use sessions without a sqlite database?

ire4ever1190 commented 8 months ago

(typing on phone so sorry if code doesn't compile =P)

import pkg/[mike, anano]
import std/[options, tables]

# Same thing as before, except we use a global table 
type
  Session = object
    someData: string

proc initSession(data: string): Session =
  result.someData = data

var db: Table[string, Session]

# You'll want a route to create the session
"/session" -> post:
  let
    session = initSession("hello")
    id= $genNanoID()
  # now instead of adding to the db, append to table
  db[id] = session
  ctx &= initCookie("session", id)

# Then it can be used in other routes
"/someData" -> get(session: Cookie[string]):
  # now just normal table access
  let foundSess = db[session]
  ctx.send("Your data is " & foundSess.someData)

# You could also make a hook if you are using the session in multiple places
proc fromRequest(ctx: Context, name: string, T: typedesc[Session]): T =
  let sessionID = ctx.fromRequest("session", Cookie[string])
  if sessionID in db:
    result = db[sessionID]
  else:
    raise newBadRequestError("Missing session cookie")

"/someOtherPlace" -> get(session: Session):
  ctx.send(session.someData)

Although do note that this has no persistence

AritraBanik08 commented 8 months ago

Thank you for your help.

AritraBanik08 commented 8 months ago

I think it's much better than jester. Why is it still not added to the awesome-nim repo?

AritraBanik08 commented 8 months ago

I have another question here I have used redis to send data from one link to another. Is there a better way to do this in mike? If yes, can you show it to me.

ire4ever1190 commented 8 months ago

I think it's much better than jester. Why is it still not added to the awesome-nim repo?

Guess no one made a PR to add it haha

AritraBanik08 commented 8 months ago

Can you tell me why the session cookie is not working on the line 240 and 241 here. It's working sometimes and not working other times now the session cookies are working only on chrome and not in firefox and safari.

ire4ever1190 commented 8 months ago

Thats weird, are you accidently switching between 127.0.0.1 and localhost (I did that a lot during an assignment and was confused how I kept getting logged out)

AritraBanik08 commented 8 months ago

@ire4ever1190 no I am only using 127.0.0.1 I don't know what is happening. This is wierd and is not letting me login.

ire4ever1190 commented 8 months ago

Using firefox on linux, can login and view cart

AritraBanik08 commented 8 months ago

No I am saying it sometimes works and sometimes it doesn't an once it stops working it doesn't work for the whole day. I am currently using a Mac and it is working on firefox and chrome but not on safari.

ire4ever1190 commented 8 months ago

Hmm can't seem to reproduce, and don't have any safari devices to test with

Do you have a series of steps I can follow that lead to it happening?

AritraBanik08 commented 8 months ago

No there are no steps to follow here you just need to clone the repo and run nim c -r src/a3.nim then go to the website and go to the login page http://127.0.0.1:8080/login. And as a side note it started working on chrome and firefox but still no working in safari. This is the second time this has happened.

ire4ever1190 commented 8 months ago

Hmm, could you try passing secure = false to the initCookie calls?

Think that might be the problem since it seems safari doesn't allow secure cookies on localhost even though firefox and chrome do. Think I might default it to false so that there are less surprises like this

AritraBanik08 commented 8 months ago

Yes it's now working thanks.