用户Cookie验证随机失败

I'm using two structs to hold user's info

// SecureDevice holds a user's device's infos
type SecureDevice struct {
    Name     string // Defined by the user
    DeviceIP string
    Token    struct {
        Token        string
        StartingDate time.Time // The token is supposed to last only a week before becoming invalid
    }
}

// GlobalUser is a struct defining all user's infos registered inside the server
type GlobalUser struct {
    Username          string
    Password          string
    Salt              string
    Mail              string
    ValidationToken   string // Used to validate the user's mail adress
    Lang              string
    ConversationsID   []int // The private messages the user has part in
    SecureDevicesList []SecureDevice
}

And I'm using a function to check if the user is logged in

// IsLoggedIn checks if client's token is valid
func IsLoggedIn(r *http.Request) string {
    ips := strings.Split(r.Header.Get("X-Forwarded-For"), ", ")
    ip := ips[0]
    cookie, err := r.Cookie("auth")
    if err != nil {
        return "ERR$" + "not_connected"
    }
    cookieValue := strings.Split(cookie.Value, "$")
    println(cookie.Value)
    user := GetUser(cookieValue[0])
    userToken := cookieValue[1]
    if user.Username == "" {
        return "ERR$" + "error"
    }
    for _, SecureDevice := range user.SecureDevicesList {
        if SecureDevice.DeviceIP == ip && SecureDevice.Token.Token == userToken { // We make sure that the token provided is actually the user's token
            if time.Since(SecureDevice.Token.StartingDate)*time.Hour >= 168 { // If token is older than 1 week, we throw it away
                return "ERR$" + "error_token_expired"
            } else if time.Since(SecureDevice.Token.StartingDate)*time.Second >= 30 { // If it's age is between 1 hour and one week, we renew it
                db, err := scribble.New("./brony/db", nil)
                if err != nil {
                    return "ERR$" + "error_internal"
                }
                tokenBytes, err := GenerateRandomBytes(64) // Generates a salt
                if err != nil {
                    return "ERR$" + "error_internal"
                }
                token := base64.URLEncoding.EncodeToString(tokenBytes)
                SecureDevice.Token.Token = token
                SecureDevice.Token.StartingDate = time.Now()
                errr := db.Write("users", user.Username, user)
                if errr != nil {
                    return "ERR$" + "error_internal"
                }
                return "TOK$" + user.Username + "$" + SecureDevice.Token.Token
            } else if time.Since(SecureDevice.Token.StartingDate)*time.Hour <= 1 {
                return "NIL$"
            }
        } else if SecureDevice.DeviceIP == ip {
            return "ERR$" + "error_bad_token"
        }
    }
    return "ERR$" + "error_device_not_registered"
}

But almost always when I load the page with

status := IsLoggedIn(r)
println(status)

It often gives me an error, since I'm printing "IsLoggedIn" to understand where the problem comes from

test$ppDXRggtztyA9OBbdZh1t1ESqRo2XvuOBt4xlDai9kVxwq-_3zlWyvgNgA7AZcSpasJ_YnXZvoG                                                                                                                                                             qlz1syF9X8g==
NIL$

test$ppDXRggtztyA9OBbdZh1t1ESqRo2XvuOBt4xlDai9kVxwq-_3zlWyvgNgA7AZcSpasJ_YnXZvoG                                                                                                                                                             qlz1syF9X8g==
ERR$error_token_expired

test$ppDXRggtztyA9OBbdZh1t1ESqRo2XvuOBt4xlDai9kVxwq-_3zlWyvgNgA7AZcSpasJ_YnXZvoG                                                                                                                                                             qlz1syF9X8g==
NIL$

test$ppDXRggtztyA9OBbdZh1t1ESqRo2XvuOBt4xlDai9kVxwq-_3zlWyvgNgA7AZcSpasJ_YnXZvoG                                                                                                                                                             qlz1syF9X8g==
ERR$error_token_expired
test$ppDXRggtztyA9OBbdZh1t1ESqRo2XvuOBt4xlDai9kVxwq-_3zlWyvgNgA7AZcSpasJ_YnXZvoG                                                                                                                                                             qlz1syF9X8g==
ERR$error_token_expired

test$ppDXRggtztyA9OBbdZh1t1ESqRo2XvuOBt4xlDai9kVxwq-_3zlWyvgNgA7AZcSpasJ_YnXZvoG                                                                                                                                                             qlz1syF9X8g==
ERR$error_token_expired

test$ppDXRggtztyA9OBbdZh1t1ESqRo2XvuOBt4xlDai9kVxwq-_3zlWyvgNgA7AZcSpasJ_YnXZvoG                                                                                                                                                             qlz1syF9X8g==
ERR$error_token_expired

test$ppDXRggtztyA9OBbdZh1t1ESqRo2XvuOBt4xlDai9kVxwq-_3zlWyvgNgA7AZcSpasJ_YnXZvoG                                                                                                                                                             qlz1syF9X8g==
ERR$error_token_expired

test$ppDXRggtztyA9OBbdZh1t1ESqRo2XvuOBt4xlDai9kVxwq-_3zlWyvgNgA7AZcSpasJ_YnXZvoG                                                                                                                                                             qlz1syF9X8g==
NIL$

At first I thought it was my token's renewal code which was faulty, but while beeing faulty and unfinished, it doesn't seem to be it's fault since after a few f5, it said that the cookie was ok. I really don't understand where the fault is, and it's starting to get really annoying, as I can't just let it be, it would be very annoying to say the least for a user to do f5 everytime and hope that when the page will refresh, it will miraculously work. The code runs on a debian server

Your issue might be, the way you handle time.Since return value for comparison.

time.Since method returns type Duration and internally represented as type int64. Value is in Nanoseconds.

Try this-

elapsedHours := int64(time.Since(SecureDevice.Token.StartingDate).Hours())
if elapsedHours >= 168 {
    //...
} else if elapsedHours >= 30 {
   //...
} else if elapsedHours <= 1 {
   //...
}