Просмотр исходного кода

init session by browser cookie too.

master
sp 4 лет назад
Родитель
Сommit
46257e4b29
1 измененных файлов: 73 добавлений и 17 удалений
  1. +73
    -17
      apiv1.go

+ 73
- 17
apiv1.go Просмотреть файл

@@ -5,9 +5,11 @@ import (
"database/sql"
"encoding/json"
"fmt"
"github.com/brianvoe/gofakeit/v6"
log "github.com/sirupsen/logrus"
"net/http"
"net/http/httputil"
"strconv"
"strings"
"time"
)
@@ -31,14 +33,19 @@ func apiV1Main(w http.ResponseWriter, r *http.Request) {
logRequestDebug(httputil.DumpRequest(r, true))
w.Header().Set("Content-Type", "application/json;charset=UTF-8")

//track browser, and take session from cookie
session := loan.Session{}
apiV1InitSessionByBrowserId(w, r, &session)

//try session login first, if not an empty session will be created
session, e := apiV1InitSession(r)
e := apiV1InitSessionByHttpHeader(r, &session)
if e != nil {
log.Warnf("Fail to InitSession %+v", session)
apiV1Client403Error(w, r)
return
}
session.RenewIfExpireSoon()
session.SetRemote(r) //make sure they are using latest remote

//we have a session now, either guest or valid user
//search through handler
@@ -53,29 +60,78 @@ func apiV1Main(w http.ResponseWriter, r *http.Request) {
return
}
}

//Catch for all
e = session.Write() //finish this session to DB
apiV1DumpRequest(w, r, &session)
}

func apiV1InitSession(r *http.Request) (session loan.Session, e error) {
session = loan.Session{}
sid := r.Header.Get("Biukop-Session")
e = session.Retrieve(r)
if e == nil { //we got existing session
e = session.ValidateRequest(r)
if e != nil { // not successfully validated
log.Warnf("failed session login %+v, %s", session, time.Now().Format(time.RFC1123))
func apiV1InitSessionByBrowserId(w http.ResponseWriter, r *http.Request, session *loan.Session) {
var mid string
inCookie, e := r.Cookie("mid")
if e == nil {
mid = inCookie.Value
} else {
mid = strconv.Itoa(int(time.Now().Unix())) + "-" + gofakeit.UUID()
}

var sid string
inCookie, e = r.Cookie("session")
if e == nil {
sid = inCookie.Value
if sid != "" {
e = session.Read(sid)
if e == nil {
if mid != session.Get("mid") {
session.MarkEmpty()
}
}
} else { //create a new session
session.InitGuest(time.Now().Add(loan.DefaultSessionDuration))
e = nil
} //else, we have logged this user in
} else if e == sql.ErrNoRows {
log.Warn("DB has no corresponding session ", sid)
session.InitGuest(time.Now().Add(loan.DefaultSessionDuration))
session.Add("mid", mid)
}
}

//add tracking cookie
expiration := time.Now().Add(365 * 24 * time.Hour)
cookie := http.Cookie{Name: "session", Value: session.Id, Expires: expiration}
http.SetCookie(w, &cookie)

cookie = http.Cookie{Name: "mid", Value: mid, Expires: expiration}
http.SetCookie(w, &cookie)

}

func apiV1InitSessionByHttpHeader(r *http.Request, ss *loan.Session) (e error) {
sid := r.Header.Get("Biukop-Session")

//make sure session id is given
if sid != "" {
//Try to retrieve a copy of DB session
trial := loan.Session{}
e = trial.Retrieve(r)
if e == nil { //we got existing session from DB
e = trial.ValidateRequest(r)
if e != nil { // db session does not match request
log.Warnf("failed session login %+v, %s", ss, time.Now().Format(time.RFC1123))
ss.InitGuest(time.Now().Add(loan.DefaultSessionDuration))
e = nil
} else { //else, we have logged this user
*ss = trial //overwrite the incoming session
}
} else if e == sql.ErrNoRows { //db does not have required session.
log.Warn("DB has no corresponding session ", sid)
} else { // retrieve has error
log.Warnf("Retrieve Session %s encountered error %s", sid, e.Error())
}
}

//if there is not session incoming
if ss.IsEmpty() { //cookie may have initialized a session
ss.InitGuest(time.Now().Add(loan.DefaultSessionDuration))
e = nil //we try to init an empty one
} else {
log.Warnf("Retrieve Session %s encountered error %s", sid, e.Error())
}
session.SetRemote(r) //make sure they are using latest remote

return
}


Загрузка…
Отмена
Сохранить