Обновление переменных сеанса выводит пользователя на страницу входа или нет?

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

<cfset local.appStruct = structNew()>
<cfset structInsert(local.appStruct, "SysAdmin", checkUser.SystemAdmin, true)>
<cfset structInsert(local.appStruct, "UserName", checkUser.UserName, true)>
<cfset structInsert(local.appStruct, "AccountID", checkUser.AccountID, true)>
<cfset structInsert(local.appStruct, "Email", checkUser.Email, true)>
<cfset structInsert(local.appStruct, "TempPW", checkUser.TempPassword, true)>
<cfset structInsert(local.appStruct, "AccessType", permissionType, true)>
<cfset structInsert(local.appStruct, "AccessLevel", permissionLevel, true)>
<cfset structInsert(local.appStruct, "AccessList", permissionList, true)>
<cfset SESSION.AccountInfo = appStruct> 

Выше я просто показал поля, которые сохраняются в области сеанса. Все значения взяты из запроса, который я не показывал. Например, TempPW хранит временный пароль, и мне не нужно его обновлять, поскольку пользователь будет автоматически перемещен на страницу входа в систему после установки нового пароля. В других ситуациях, когда они обновляют email или access type, я не уверен, следует ли мне выйти из системы или попытаться обновить область сеанса? Есть ли какой-либо риск для безопасности, делая это так или иначе? Я просто пытаюсь реализовать лучшие практики в своем приложении. Спасибо.


person espresso_coffee    schedule 25.07.2018    source источник
comment
Не связано, но обычно вы не храните пароли (любые пароли) в переменных сеанса.   -  person SOS    schedule 26.07.2018
comment
@Ageax Это не настоящий пароль, а просто флаг 1 или 0. Пользователи с временным паролем вынуждены сменить пароль и снова войти в систему.   -  person espresso_coffee    schedule 26.07.2018
comment
О, ладно, хорошо :) Обычно я называю логические переменные с помощью IsSomething или HasSomething, чтобы их тип был ясен, но это всего лишь вопрос предпочтений.   -  person SOS    schedule 26.07.2018


Ответы (2)


С точки зрения пользователя необходимость выходить из системы и снова входить в нее звучит далеко не идеально.

Я предлагаю обновлять область сеанса, когда пользователь обновляет свою электронную почту или другие значения. В этом не должно быть никакой разницы в безопасности по сравнению с требованием, чтобы пользователь вышел из системы и снова вошёл в систему.

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

<cfset SESSION.AccountInfo.Email = form.email>
<cfset SESSION.AccessLevel = "SOME_NEW_ACCESS_LEVEL">
etc...

В качестве дополнительной рекомендации я бы прекратил использовать structInsert, вы можете просто установить переменную и избежать (чрезвычайно небольших) накладных расходов на вызов функции. Ваш тот же код выше можно переписать как:

<cfset local.appStruct = structNew()>
<cfset local.appStruct.SysAdmin = checkUser.SystemAdmin>
<cfset local.appStruct.UserName = checkUser.UserName>
<cfset local.appStruct.AccountID = checkUser.AccountID>
<cfset local.appStruct.Email = checkUser.Email>
<cfset local.appStruct.TempPW = checkUser.TempPassword>
<cfset local.appStruct.AccessType = permissionType>
<cfset local.appStruct.AccessLevel = permissionLevel>
<cfset local.appStruct.AccessList = permissionList>
<cfset SESSION.AccountInfo = appStruct> 

Если по какой-то причине вам нужно сохранить регистр ключей структуры, вы можете использовать синтаксис стиля массива, например:

<cfset local.appStruct = structNew()>
<cfset local.appStruct["SysAdmin"] = checkUser.SystemAdmin>
<cfset local.appStruct["UserName"] = checkUser.UserName>
<cfset local.appStruct["AccountID"] = checkUser.AccountID>
<cfset local.appStruct["Email"] = checkUser.Email>
<cfset local.appStruct["TempPW"] = checkUser.TempPassword>
<cfset local.appStruct["AccessType"] = permissionType>
<cfset local.appStruct["AccessLevel"] = permissionLevel>
<cfset local.appStruct["AccessList"] = permissionList>
<cfset SESSION.AccountInfo = appStruct> 

Вы можете использовать <cfdump, чтобы увидеть различия между двумя структурами и то, как ключи либо все в нижнем регистре в первом примере, либо их верхний/нижний регистр сохраняется во втором примере.

<cfdump var="#local.appStruct#" />

Извините, может быть, я отклоняюсь от темы, надеюсь, это поможет.

person Greg Stevens    schedule 25.07.2018
comment
Таким образом, вместо использования structUpdate() вы бы порекомендовали использовать точечную запись и перезаписать предыдущее значение? Примечание: довольно просто: я могу обновить Username, Email, PermissionType и PermissionLevel, но обновить PermissionList не так просто, поскольку я создаю это при входе пользователя в систему. Этот процесс требует циклического перебора разрешений и установки их в определенной группе на основе учетных данных. В любом случае спасибо за вашу помощь. - person espresso_coffee; 26.07.2018
comment
Ааа, хорошо, удачи! Не могли бы вы переместить эту логику PermissionList в CFC, чтобы вы могли вызывать такую ​​функцию, как <cfset local.appStruct.PermissionList = User.generatePermissionList()> ?? И я мог неправильно понять ваш вопрос, но, поскольку SESSION.AccountInfo.PermissionList устанавливается при входе в систему, он все равно будет существовать, когда вы обновите SESSION.AccountInfo.Email, - еще раз извините, если я неправильно понял. - person Greg Stevens; 26.07.2018
comment
Он все еще будет существовать, но я говорю, что если пользователь обновит свои разрешения, я должен сравнить, отличаются ли они, а затем создать новый список и назначить область сеанса. - person espresso_coffee; 26.07.2018
comment
Или вы также можете сэкономить гораздо больше времени на наборе текста и использовать <cfset local.appStruct = { SysAdmin : checkUser.SystemAdmin , UserName : checkUser.UserName, ... } >. Мое предложение состояло бы в том, чтобы использовать синтаксис cfscript, так как это новый dev. Делать многие вещи намного проще. - person Shawn; 26.07.2018

Это не ответ, а скорее комментарий о том, как упростить создание Struct.

Как я уже упоминал в комментарии к ответу @ sqrl0, с тегами вы можете использовать:

<cfset local.appStruct = {
    "SysAdmin"    : checkUser.SystemAdmin ,
    "UserName"    : checkUser.UserName ,
    "AccountID"   : checkUser.AccountID ,
    "Email"       : checkUser.Email ,
    "TempPW"      : checkUser.TempPassword ,
    "AccessType"  : permissionType ,
    "AccessLevel" : permissionLevel ,
    "AccessList"  : permissionList
}>
<cfset SESSION.AccountInfo = local.appStruct> 

Или CFScript: ПРИМЕЧАНИЕ. Вам не нужно копировать структуру в SESSION.AccountInfo. Вы можете просто создать его там.

<cfscript>
  SESSION.AccountInfo = {
    "SysAdmin"    : checkUser.SystemAdmin ,
    "UserName"    : checkUser.UserName ,
    "AccountID"   : checkUser.AccountID ,
    "Email"       : checkUser.Email ,  
    "TempPW"      : checkUser.TempPassword ,
    "AccessType"  : permissionType ,
    "AccessLevel" : permissionLevel ,
    "AccessList"  : permissionList
  }
</cfscript>

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

person Shawn    schedule 26.07.2018
comment
Спасибо за пример. Я немного смущен тем, что вы пытаетесь объяснить в своем последнем комментарии о перезаписи переменных... - person espresso_coffee; 26.07.2018
comment
Если у вас есть SESSION.AccountInfo.email, а затем вы создаете local.appStruct.email и копируете appstruct в SESSION.AccountInfo, вы перезапишете SESSION.AccountInfo.email на local.appStruct.email. - person Shawn; 26.07.2018
comment
Отличная демонстрация создания более коротких структур @Shawn! - person Greg Stevens; 27.07.2018