нестабильный метод аутентификации net / http - PullRequest
1 голос
/ 14 марта 2019

Я создал свой собственный метод аутентификации (и аутентификации в одном сеансе), который сохраняет сеанс в Redis, метод:

  1. Я проверяю, есть ли в браузере файл cookie с моего сервера, если нет, тосоздать и сохранить в браузере
  2. проверить, существует ли идентификатор куки на redis, если да, следующий шаг, если не перенаправить на логин
  3. проверить, какое значение redis по идентификатору куки в качестве ключа, значение будет именем пользователя, если имя пользователя существует, проверьте значение get в redis по имени пользователя, если имя пользователя имеет значение идентификатора cookie, а затем сравните, совпадает ли идентификатор cookie с текущим идентификатором браузера, если нет, перенаправьте на логин

Код

before_request:

func (hs BeforeRequest) ServeHTTP(w http.ResponseWriter, r *http.Request) {

    if !strings.Contains(r.RequestURI, "/login") && !strings.Contains(r.RequestURI, "/logout") {

        // Check is user has `guid` cookie
        Guid, err := r.Cookie("guid")

        // if cookie not available, set cookie and redirect to login
        if err != nil {

            // Set the cookie
            expiration := time.Now().Add(365 * 24 * time.Hour)
            cookie := http.Cookie{Name: "guid", Value: helper.GenerateGuid(), Expires:expiration}
            http.SetCookie(w, &cookie)

            // Redirect to login
            http.Redirect(w, r, "/login", 301)
            return
        } else {

            // Return username that used by user (by it's Guid)
            _, err := redisdb.Get(Guid.Value).Result()

            if err != redis.Nil {

                // Get active Guid by username, return active Guid
                UsedFor, err := redisdb.Get(IsHasRedis).Result()

                if err != redis.Nil && err == nil {
                    if UsedFor != Guid.Value {
                        fmt.Println("this account used in another session")
                        http.Redirect(w, r, "/login", 301)
                        return
                    }
                } else {
                    // definitely not logged in
                    http.Redirect(w, r, "/login", 301)
                    return
                }

            } else {
                // definitely not logged in
                http.Redirect(w, r, "/login", 301)
                return
            }

        }

    }

    // handle the request.
    hs[0].ServeHTTP(w, r)
}

логин:

func LoginExecute(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    err := r.ParseForm() // Must be called before writing response

    if err != nil {
        fmt.Println(err)
    } else {
        if processRequest(r) {
            Username, Password := r.Form["username"], r.Form["password"]

            if len(Username) > 0 && len(Password) > 0 {

                if len(Username[0]) <= 20 && len(Password[0]) <= 50 {

                    User := structs.Users{}

                    database, err := helper.DataDatabase()

                    if err != nil {
                        http.Error(w, "Couldn't Connect to Database", 500)
                        return
                    }

                    err = database.C("users").Find(bson.M{"username": Username[0]}).One(&User)

                    if err == nil {
                        CompareError := bcrypt.CompareHashAndPassword([]byte(User.Password), []byte(Password[0]))

                        if CompareError == nil {

                            Guid, err := r.Cookie("guid")

                            if err == nil {

                                redisdb.Set(Guid.Value, Username[0], 6 * time.Hour)
                                redisdb.Set(Username[0], Guid.Value, 6 * time.Hour)

                                http.Redirect(w, r, "/", 301)
                            } else {
                                http.Redirect(w, r, "/login?err=disabled-cookie", 301)
                            }

                        } else {
                            http.Redirect(w, r, "/login?err=password", 301)

                        }
                    } else {

                        http.Redirect(w, r, "/login?err=username", 301)
                    }
                }
            }
        } else {
            // recaptcha failed
            http.Redirect(w, r, "/login?err=username", 301)
        }
    }
}

проблема в том, что этот метод аутентификации был нестабильным, IDK почему, но после того, как пользователь успешно логинится:

  1. доступ / перенаправление блога для входа в систему
  2. доступ / блог (с открытым инструментом разработчика) работает
  3. доступ / настройки работают
  4. через несколько минут / часов доступа/ настройки перенаправить на / логин
  5. я делаю вход, успех, доступ / настройки, перенаправлен на / вход снова

да просто нестабильно

примечание:

  1. я использую "github.com / julienschmidt / httprouter "для маршрутизации
  2. " github.com/go-redis/redis "для redis

1 Ответ

2 голосов
/ 14 марта 2019

Статус ответа 301 означает «Перемещено постоянно», что позволяет браузерам бесконечно кэшировать ответ. Вместо этого используйте 302 Найдено для перенаправления или вообще не перенаправляйте (вы можете просто сразу открыть страницу входа).

Открытие инструментов разработчика, скорее всего, отключило кэширование, чтобы оно заработало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...