LINUX.ORG.RU

Как сделать сессию?

 , , ,


0

1

Хочу понять саму логику как сделать сессию. Прочитал как она работает в rails: создается id сессии на основе случайного числа + секретный ключ, вот сделал так же, id сессии генерируется. Может оно везде одинаково делается, на php и python и точно поможете. Вот есть id сессии - и что с ним дальше делать? Как с его помощью можно зашифровать хэш значений вроде user_id: 1 и потом обратно расшифровать?


Получилось!!1! Ура Уверен всем интересно, расскажу. Сохранение в сессию так: s = encode_base64 json_encode tbl Где tbl это таблица значений, а прочее - функции которые надо подключить из готовых либ. Потом к строке s добавляем «\n--» + encode_base64 hmac_sha1 secret, s Где hmac_sha1 тоже надо подключить, а «s» делалась выше. Результат можно сохранять в куку: «session=» + uri.escape(s) + "; path=/" uri escape важно не забыть, иначе ничего не выйдет. И вот уже сессия сохранена в куки! А потом чтобы её достать: cookie = uri.unescape куку сессии Матчим регекспом «^(.*)\n%-%-(.*)$» по cookie два результата: 1 - таблицу значений и 2 - подпись. Этот регексп переписать под ваш ЯП. Проверяем подпись: если полученная регекспом подпись == encode_base64 hmac_sha1 secret, str где str - это полученный из регекспа json с таблицей значений, то все ок, иначе подпись неправильная. И дальше все что остается это распарсить json, сессия готова.

Romaboy
() автор топика
Ответ на: комментарий от Romaboy

прости за то что испорчу ощущение счастья, но сессию не хранят на стороне клиента, это не безопасно. На клиенте только идентификатор сессии, само значение храни как тебе удобно, хоть классами на сервере сериализуй.

TBEPDb
()
Ответ на: комментарий от TBEPDb

В этом нет ничего не безопасного.
Вы и так не должны доверять любым данным, которые приходят от пользователя в явном виде, поэтому говорить о безопасности в данном случае не уместно.
Хранить все данные сессии на клиенте - одна из известных практик. Для этого данные шифруются и подписываются ключом с сервера. Такой подход, имеет как свои недостатки (например, если данных много, то и результат отправляемый клиенту будет довольно «тяжелым»), так и преимущества (например, одно из самых явных - возможность любого сервера, владеющего ключом, восстановить сессию пользователя).

znenyegvkby
()
Ответ на: комментарий от znenyegvkby

Насчет не безопастности: всетаки в сессии довольно часто хранится, так сказать, результат аворизации(роль пользователя в системе). Хранить такое на клиенте несколько не безопасно. Есть конечно выход, проводить авторизацию для каждого запроса, но это както затратно по отношению к серверу.
Тянуть всю сессию через сеть каждым запросом тоже не выглядит изящным решением. А плюс востановления сессии любым сервером можно получить и через хранение сессии не в памяти процесса(memcache, redis, db, etc).

TBEPDb
()
Ответ на: комментарий от TBEPDb

Насчет не безопастности: всетаки в сессии довольно часто хранится, так сказать, результат аворизации(роль пользователя в системе). Хранить такое на клиенте несколько не безопасно.

Если у вас на примете есть проекты, хранящие роли в данных сессии, хотелось бы увидеть ссылки. Просто хранить доп. данные сессии (и даже пользователя!, здесь есть одно но, о нем чуть ниже) на клиенте - действительно распространенная практика. Можете, например, посмотреть реализацию той же Mozilla Persona, но и то, если пройтись по коду, станет понятно что проблему закрытия сессии на клиенте они решают путем хранения спец. записи на сервере. Т.е. не все состояние хранится на стороне клиента.
Но там нет и не может быть никаких данных, однозначно позволяющих провести аутентификацию пользователя, либо его идентификацию, либо просто данных, относящихся к разряду личной информации. Права доступа, как правило, относятся к личному профилю пользователя (если какие-то конкретные данные к личной информации не относятся, их действительно можно хранить на клиенте, о том, что является их показателем, немного ниже). Тот, кто хранит личные данные в сессии, путает причину и следствие. Объясняю по порядку:

  1. Сессия - временный слепок, полученный в результате аутентификации конкретного пользователя. Т.е. это результат какого-либо действия. У клиента есть слепок, по которому сервер может восстановить уже выполненное действие. Но у клиента ни в коем случае нет и не может быть данных, которые позволят повторить это действие.
  2. Теперь о личных данных. Для начала один немаловажный аспект - любая доп. информация, хранимая в сессии, должна переживать ее время, иначе ни передавать, ни хранить ее - не имеет смысла. Критерий личной информации задается конкретным ПО. Скажем возраст пользователя, и дата рождения. В какой-нибудь «недосоциалочке» - дата рождения зачастую будет являться личной информацией, а вот возраст вполне себе может храниться в сессии. Но еще раз - все зависит от конкретного ПО. Например в банковских сферах, практически ко всем данным пользователя нужно относиться с особой осторожностью. Особенно к ролям доступа. И шифрование не спасет. Священный молот на вас обрушат когда выявят сам факт хранения личных данных в непроверенном источнике :)

Тянуть всю сессию через сеть каждым запросом тоже не выглядит изящным решением.

Это уже относится к деталям реализации. Можно хранить минимизированный слепок, и за счет небольшой избыточности при первом запросе, экономить трафик при следующих, не в ущерб безопасности. В любом случае вариантов предостаточно.

А плюс востановления сессии любым сервером можно получить и через хранение сессии не в памяти процесса(memcache, redis, db, etc).

А вот этого не понял. Вы предлагаете хранить инфу для восстановления в каком-то централизованном хранилище, куда каждый отдельный сервер будет выполнять еще один запрос?

znenyegvkby
()
Ответ на: комментарий от TBEPDb

Ответ г-на znenyegvkby не прочитал так как текста много, вот как оно работает в моей реализации, полностью с rails взятой: в сессии хранится только user_id. Он зашифрован, но хакерок может если захочет его расшифровать. Что это даст? Ничего! :) Юзер при каждом запросе из базы берется, авторизуется только один раз и его id сохраняется в сессию, а потом считается авторизованным, ведь если сессию вручную поменять - зашифрованное значение станет невалидным и она не пройдет. Хранить данные пользователя в сессии - это отличная идея, тогда и к базе не надо будет обращаться. Если хакер похитит сессию админа, расшифрует и поймет, что это админ - это все, ну узнает он что ему админ попался, использовать сессию все равно не сможет, ведь её ключ постоянно меняется. Вывод - сессия это отличная негрузящая вполне безопасная база данных с одним лишь минусом - размер маленький.

Romaboy
() автор топика
Ответ на: комментарий от znenyegvkby

На счет примера, можно смотреть фактически любой веб проект, все что сложнее сайта визитки хранит состояние, использует для этого сессии.
Не буду спорить, просто укажу что большинство проектов идет по пути хранения ключа сессии на клиенте а данных сессии на сервере.
Конечно можно реализовать все что угодно, но типовым решение будет всетаки хранение сессии на сервере.

А вот этого не понял. Вы предлагаете хранить инфу для восстановления в каком-то централизованном хранилище, куда каждый отдельный сервер будет выполнять еще один запрос?

Да, это много быстрее чем тянуть сессию с клиента через мобильную связь, да и много быстрее для клиента с приличной связью. Поскольку хранилище будет минимум в локальной сети серверов.

Вообще, мне просто лень спорить и убеждать, попробуйте подойти к вопросу с позиции: «Как это сделали другие?». Я даже подкажу запрос в гугл «Хранение сессии».

TBEPDb
()
Ответ на: комментарий от TBEPDb

Не буду спорить, просто укажу что большинство проектов идет по пути хранения ключа сессии на клиенте а данных сессии на сервере.

Дак оно разумеется, что хранить на сервере — самая распространенная практика. Но вы почему-то забыли что мы как-бэ начали разговор именно о хранении на стороне клиента. В частности о безопасности этого способа :)

Да, это много быстрее чем тянуть сессию с клиента через мобильную связь, да и много быстрее для клиента с приличной связью. Поскольку хранилище будет минимум в локальной сети серверов.

Вот. Уже ближе к теме. Только не факт что это будет быстрее. Централизованный сервер - это больше проблем, чем запрос от клиента. Во-первых, горизонтально масштабировать сложнее. Во-вторых, синхронизировать данные нужно от всех клиентов. В-третьих, доступность этих самых данных, и т.д. и т.п. А насчет мобильной связи, ну для этого есть сжатие. Вы думаете там мегабайты данных что-ли перекачивают?

да и много быстрее для клиента с приличной связью

Вы честно скажите, вы когда-нибудь пользовались децентрализованной системой авторизации OpenID/MP/etc со своего мобильника? (ну полюбому же на говнокоде сидите:)) Некоторые из них как раз используют подход хранения сессии на клиенте, и никаких проблем со связью не испытывают. Как раз наоборот, проблемы в основном у всяких серверов, которые то недоступны вдруг оказываются, то медленно отдают ответ, то еще что-нибудь.

znenyegvkby
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.