我想知道网络应用通常遵循的在多个请求之间保持登录的过程,以及它们如何使用 COOKIES 进行管理。
在我的登录表单中,我提供了“记住我”功能。
当用户登录时,我会从数据库中检查用户名和密码的有效性。如果它有效,那么我检查是否选择了“记住我”,如果是,则将用户名和密码存储在 session 中,加密格式。最后将用户名和密码存储在 SESSION 中。
当用户从一个页面导航到另一个页面时,首先我运行登录检查脚本检查 cookie 中是否有任何值,然后它从数据库中验证用户名和密码,以检查其有效性。如果 cookie 中没有值而 session 中有一些值,那么我正在获取 session 值并且不从 db 中检查它。
我没有检查数据库中的 session 值,以免不必要地访问数据库,加快速度。如果是 cookie,则可以修改它们,因此需要检查。
这就是我的概念,对吗?这是要走的路,通常像 SO 这样的网站,以及其他采用这种方法的作品吗?
或者网站在每次加载页面时检查登录真实性,无论是在 session 中还是在 cookie 中?
请检查并给出您对此场景的想法和概念。
谢谢!
最佳答案
首先,只跟踪是否有人登录。之后,我们将处理“记住我”功能。
要知道是否有人登录,只需查看 $_SESSION 数组即可。那里的一切都是因为你之前把它放在那里。因此,在处理登录表单时,如果用户名和密码正确,那么您将在 session 中存储用户名、用户 ID 或其他任何内容 ($_SESSION['username'] = $username;)。
每当用户加载任何页面时,您只需检查
if (isset($_SESSION['username'])) {
// $_SESSION['username'] is logged in
} else {
// nobody is logged in
}
没有必要将密码存储在$_SESSION中(事实上,为了安全起见,最好不要将其存储在数据库中哈希之外的任何地方)。
现在,“记住我”功能......首先,一些注意事项:
对于第一点,假设您在 cookie 上存储了要“记住”的用户的用户名(非常不安全!!)。这意味着,如果任何用户为您的 Web 应用程序创建了内容为“joe”的 cookie,您的应用程序将认为该计算机中记住了用户 joe,因此向该攻击者授予访问权限,就好像他/她是 joe 一样。因此,我们需要以某种方式对 cookie 进行加密/哈希处理。
对于第二点,在某些计算机上使“记住我”无效,我们将以某种方式使用密码。如果某个用户想要使他/她可能选中“记住我”复选框的所有计算机无效,他/她所要做的就是更改他/她的密码。这也意味着,如果他/她更改了他/她的密码,则出于同样的确切原因,他/她帐户的所有已保存登录信息都将失效。但安全总比后悔好...
因此,当您处理登录且用户名和密码正确且选中“记住我”选项时,除了在 session 中保存用户名外,您还存储了用户名和密码的哈希值(以及一些盐,如果你愿意的话)在你发送给用户的cookie中。此外,您还需要在 cookie 中以纯文本形式(或以可逆方式加密)存储用户名,以了解哪个用户试图通过 cookie“登录”,并检查 cookie 中用户名和密码的哈希值以及数据库中的用户名和密码。如果该检查正确,则您将用户名存储在 session 中并且不再检查该用户的 cookie(至少对于该 session )。
因此,总体而言,您的代码可能如下所示:
登录.php
if (check_login($_POST['username'], $_POST['password'])) {
// login correct
$_SESSION['username'] = $_POST['username'];
if (isset($_POST['remember_me'])) {
// we hash the password because we **NEVER** store it in plain text anywhere
// so when we would like to check if the cookie value is correct, we will not
// be able to do so if the hash in the cookie was done from the plaintext
// password.
$value = sprintf('%s:%s', $_POST['username'], md5($_POST['username'].hash_password($_POST['password'])));
setcookie('rememberme', $value);
}
redirect('/your/home/page.php'); // view Post/Redirect/Get design pattern
} else {
// login incorrect, show error message and whatever...
}
在每个 php 文件的开头(或者更好,在用于引导您的应用程序的包含文件中)
if (isset($_SESSION['username'])) {
// $_SESSION['username'] is logged in, proceed as you wish
} else if (isset($_COOKIE['rememberme'])) {
// this user has checked the remember me feature some time ago in a previous login.
// let's check if it is valid.
list($username, $hash) = explode(':', $_COOKIE['rememberme']);
// we need to get the password hash stored for this user (remember you **NEVER** store passwords in plain text
$pwd_hash = obtain_password_hash_from_username($username);
if ($hash == sprintf('%s:%s', $username, md5($username.$pwd_hash))) {
// yeah, the user remembered is correct. We'll save it to the session to not do this shit again
$_SESSION['username'] = $username;
} else {
// the cookie value is not correct so maybe an attacker is trying to fool us,
// or the user changed his password. Whatever it is, we remove the cookie
// because it's no longer valid
setcookie('rememberme', '', time() - 3600);
}
} else {
// this user is neither logged in nor "remembered"
}
散列用户密码的方法由您决定。您可能喜欢纯 md5 或 sha、盐渍 md5 或 sha(更好)或一些耗时的方法,如河豚(推荐)。 为了散列 cookie,我使用了普通的 md5,但您可以选择前面描述的任何方法。
我想这就是全部。
关于php - 登录系统的概念和逻辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5095503/
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。 准备工作: 1、U盘一个(尽量使用8G以上的U盘)。 2、一台正常联网可使用的电脑。 3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。 4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。 U盘启动盘制作步骤: 注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实
在Ruby中,以毫秒为单位获取自纪元(1970)以来的当前系统时间的正确方法是什么?我试过了Time.now.to_i,好像不是我想要的结果。我需要结果显示毫秒并且使用long类型,而不是float或double。 最佳答案 (Time.now.to_f*1000).to_iTime.now.to_f显示包含十进制数字的时间。要获得毫秒数,只需将时间乘以1000。 关于ruby-以毫秒为单位获取当前系统时间,我们在StackOverflow上找到一个类似的问题:
关闭。这个问题需要更多focused.它目前不接受答案。想改进这个问题吗?更新问题,使其只关注一个问题editingthispost.关闭8年前。Improvethisquestion我们有以下(以及更多)系统,我们将数据从一个应用推送/拉取到另一个:托管CRM(InsideSales.com)Asterisk电话系统(内部)横幅广告系统(openx,我们托管)潜在客户生成系统(自行开发)电子商务商店(spree,我们托管)工作板(本土)一些工作网站抓取+入站工作提要电子邮件传送系统(如Mailchimp,自主开发)事件管理系统(如eventbrite,自主开发)仪表板系统(大量图表和
我正在尝试找出一种方法来显示来自不在RAILS_ROOT下(在RedHat或Ubuntu环境中)的已安装文件系统的图像。我不想使用符号链接(symboliclink),因为这个应用程序实际上是通过Tomcat部署的,而当我关闭Tomcat时,Tomcat会尝试跟随符号链接(symboliclink)并删除挂载中的所有图像。由于这些文件的数量和大小,将图像放在public/images下也不是一种选择。我查看了send_file,但它只会显示一张图片。我需要在一个格式良好的页面中显示6个请求的图像。由于膨胀,我宁愿不使用Base64编码,但我不知道如何将图像数据与呈现的页面一起传递下去。
当您在Ruby脚本中使用系统调用时,您可以像这样获得该命令的输出:output=`ls`putsoutput这就是thisquestion是关于。但是有没有办法显示系统调用的连续输出?例如,如果您运行此安全复制命令,以通过SSH从服务器获取文件:scpuser@someserver:remoteFile/some/local/folder/...它显示随着下载进度的连续输出。但是这个:output=`scpuser@someserver:remoteFile/some/local/folder/`putsoutput...不捕获该输出。如何从我的Ruby脚本中显示正在进行的下载进度?
我需要从站点抓取数据,但它需要我先登录。我一直在使用hpricot成功地抓取其他网站,但我是使用mechanize的新手,我真的对如何使用它感到困惑。我看到这个例子经常被引用:require'rubygems'require'mechanize'a=Mechanize.newa.get('http://rubyforge.org/')do|page|#Clicktheloginlinklogin_page=a.click(page.link_with(:text=>/LogIn/))#Submittheloginformmy_page=login_page.form_with(:act