好的,所以在我的主要登录 php 页面上我有这个:
<?php
session_start();
require 'connect.php';
if(mysqli_connect_errno()) {
echo 'Failed to Connect to MySQL' . mysqli_connect_errno();
}
if(isset($_POST['submit'])) {
//Variables
$user = $_POST['username'];
$pass = md5 ($_POST['password']);
//prevent MySQL Inject
$user = stripslashes($user);
$pass = stripslashes($pass);
$query = mysqli_query($con, "SELECT * FROM tech WHERE username = '$user' and password = '$pass'") or die("Can not query the DB");
$count = mysqli_num_rows($query);
if($count == 1) {
$_SESSION['username'] = $user;
$url = 'home.php';
echo '<META HTTP-EQUIV=Refresh CONTENT="0; URL='.$url.'">';
} else {
echo 'Username and Password do not match! Try Again';
$url = 'carelogin.php';
echo '<META HTTP-EQUIV=Refresh CONTENT="2; URL='.$url.'">';
session_destroy();
}
}
?>
然后,在最顶部的每个页面上我都有这个。
<?php
session_start();
require_once 'connect.php';
if(!isset($_SESSION['username'])) {
echo "<h1>You are not an authorised user</h1>";
$url = 'carelogin.php';
echo '<META HTTP-EQUIV=Refresh CONTENT="1; URL='.$url.'">';
} else {
}
?>
大约 30 秒后,如果我单击“刷新”或者如果我前进或后退,我不会在任何这些页面上触摸我的鼠标,它会一直注销我。我不明白。我设置了所有 session ,但在短短 30 秒内我就注销了。
有人请修改我的代码以允许我保持登录状态,直到我单击注销谢谢你们!
最佳答案
我想你会发现人们会为这类事情建议一个框架,但是,如果你要尝试登录,你可能希望更彻底地拆分脚本以容纳更清晰和更可扩展的代码.另外,确保使用 ini_set("display_errors",1); error_reporting(E_ALL); 在 session_start() 之上,在测试网站时收到页面上发生的任何错误/警告的警报(在实时环境中关闭错误报告)。
这里的代码比您拥有的要复杂一些,但它应该可以保护您免受注入(inject)。请注意,每个文件的所有文件夹都应与域根 相关。另请注意,您需要使用 password_hash() 函数将所有密码存储在数据库中。您可以使用其中的一些,所有这些,或者全部都不使用,但是如果您确实使用了它,请务必阅读 PHP 手册以了解所有这些在做什么:
/core.processor/classes/class.DatabaseConfig.php
// This is your database. Fill out the credentials in the connect() method
// I use PDO because I think personally it's easier to use
class DatabaseConfig
{
private static $singleton;
public function __construct()
{
if(empty(self::$singleton))
self::$singleton = $this->connect();
return self::$singleton;
}
// This is the method that creates the database connection
public function connect($host = "localhost", $username = "username", $password = "password", $database = "database")
{
// Create connection options
// 1) Make PDO Exception errors, 2) Do real binding 3) By default prefer fetching associative arrays
$opts = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC);
$conn = new PDO('mysql:host='.$host.';dbname='.$database, $username, $password,$opts);
// Send back the database connection. You can use a "utf-8" character setting here as well...
return $conn;
}
}
/core.processor/classes/class.QueryEngine.php
// This is a simple query engine. It allows for binding (or not binding)
class QueryEngine
{
private $results;
private static $singleton;
public function __construct()
{
if(empty(self::$singleton))
self::$singleton = $this;
return self::$singleton;
}
// This method sends queries to your database
public function query($sql = false,$bind = false)
{
$this->results = 0;
// Create database connection
$db = new DatabaseConfig();
// Attempt to connect and fetch data
try {
// Bind or not bind, provided there is a bind array
// This is important to look up!
if(!empty($bind)) {
$query = $db ->connect()
->prepare($sql);
$query->execute($bind);
}
else {
$query = $db ->connect()
->query($sql);
}
$this->results = $query;
}
catch (PDOException $e)
{
die($e->getMessage());
}
return $this;
}
// This method will fetch an the associative array if used with select statement
public function fetch()
{
while($row = $this->results->fetch())
$result[] = $row;
return (!empty($result))? $result : 0;
}
}
/core.processor/classes/class.HeaderProcessor.php
// This class deals with functions that should happen before the page outputs to the browswer
class HeaderProcessor
{
private static $userData;
// This method just sits and waits for actions to happen
// This method should expand with whatever you plan to do in the future
public static function eventListener($array = array())
{
if(isset($array['action'])) {
if($array['action'] == 'login') {
if(self::getLogin($array['username'],$array['password'])) {
if(self::setSession(self::$userData)) {
$_SESSION['password'] = NULL;
}
header("Location: home.php");
exit;
}
}
elseif($array['action'] == 'logout') {
session_destroy();
header("Location: loggedout.php");
exit;
}
}
}
// Process login
private static function getLogin($user,$pass)
{
$query = new QueryEngine();
$getUser = $query ->query("SELECT * FROM `users` WHERE `username` = :0",array($user))
->fetch();
if($getUser == 0)
return false;
self::$userData = $getUser[0];
// Verify the password hash (this is why you need to store your passwords differently in your db
return password_verify($pass,$getUser[0]['password']);
}
// Assign session variables
private static function setSession($userData)
{
$_SESSION = array_filter(array_merge($userData,$_SESSION));
return true;
}
// This can set options for your site, I just threw in timezone
// as well as the class autoloader
public static function initApp($settings = false)
{
$timezone = (!empty($settings['timezone']))? $settings['timezone'] : 'America/Los_Angeles';
include_once(FUNCTIONS_DIR."/function.autoLoader.php");
date_default_timezone_set($timezone);
}
}
/core.processor/functions/function.autoLoader.php
// This function will auto load your classes so you don't have to always
// include files. You could make a similar function to autoload functions
function autoLoader($class)
{
if(class_exists($class))
return true;
if(is_file($include = CLASS_DIR.'/class.'.$class.'.php'))
include_once($include);
}
/config.php
/*** This config is located in the root folder and goes on every page ***/
// Start session
session_start();
// Define common places
define("ROOT_DIR",__DIR__);
define("CLASS_DIR",ROOT_DIR.'/core.processor/classes');
define("FUNCTIONS_DIR",ROOT_DIR.'/core.processor/functions');
// Require the page initializer class
require_once(CLASS_DIR."/class.HeaderProcessor.php");
// Initialize the autoloader for classes
// Load timezone
// You can put any other preset in this method
HeaderProcessor::initApp();
// Here is where you put in events like login, logout, etc...
HeaderProcessor::eventListener($_POST);
// Use this function to help load up classes
spl_autoload_register('autoLoader');
/login.php
<?php
// add in the config file
require(__DIR__."/config.php");
?><!DOCTYPE html>
<html>
<meta charset="UTF-8">
<title>My Login</title>
<head>
</head>
<body>
<form id="loginForm" method="post" action="">
<input name="username" type="text" />
<input name="password" type="password" />
<input name="action" type="hidden" value="login" />
<input type="submit" value="LOGIN" />
</form>
</body>
</html>
关于php - session 一直让我注销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33819716/
使用rails4,ruby2。我在rails配置中为我的cookiesession设置了30分钟的超时时间。问题是,如果我转到表单,让session超时,然后提交表单,我会收到此ActionController::InvalidAuthenticityToken错误。如何在Rails中优雅地处理这个错误?比如说,重定向到登录屏幕? 最佳答案 在您的ApplicationController:rescue_fromActionController::InvalidAuthenticityTokendoredirect_tosome_p
我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于
我正在尝试使用Sinatra中的重定向和session在网站周围传递一些数据。这是一个简化的示例,使用PrettyPrint进行调试:require'pp'require'rubygems'require'sinatra'enable:sessionsget'/'dosession[:foo]='12345'puts'session1'ppsessionredirectto('/redir')endget'/redir'doputs'session2'ppsession'helloworld'end查看Thin的输出,我看到:>>Listeningon0.0.0.0:4567,CTRL
我正在使用devise,当用户更改密码时,网站会将他们注销。我在网上读到,添加sign_in可以解决问题但不起作用,并且当密码更改时用户会注销。这是我的代码if@user.errors[:base].empty?and@user.update_attributes(params[:user])sign_in(current_user,:bypass=>true)flash[:success]="Useraccounthasbeensuccessfullyupdated"redirect_toedit_user_path(params[:site_id],@user)elserender
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它
我知道当我们不知道要传递的参数数量时会使用splat参数。我想知道我是否应该一直使用splat。每当我传递参数时使用splat参数是否有任何风险? 最佳答案 当您编写的方法确实需要具有任意数量的参数时,对于诸如Hash#values_at之类的方法,splat非常有用。但一般来说,如果一个方法实际上需要固定数量的参数,那么使用命名参数比传递数组和记住哪个位置服务于哪个目的要清楚得多。例如:defFile.rename(old_name,new_name)...end比:更清晰defFile.rename(*names)...end您
我正在处理oauth1.0(twitter和flickr)。网站工作在80端口,oauth服务器工作在8080端口算法:向oauth服务器发送ajax请求以检查用户是否有有效的access_token如果用户没有access_token或access_token已过期,则打开授权窗口在oauth服务器的用户session中保存access_token发送分享数据到oauth服务器它使用sinatra+rack:session+rack::session::sequel+sqlite来存储session。它在每个响应中发送Set-Cookie:rack.session=id我正在使用2种
我正在尝试为使用omniauth-google-oauth2gem创建session编写测试。我是否需要将env["omniauth.auth"]变量与post:create一起传递?也许当我试图这样做时,我做错了。我得到的错误如下所示...Rake测试错误1)Error:SessionsControllerTest#test_should_get_create:NoMethodError:undefinedmethod`provider'fornil:NilClassapp/models/user.rb:6:in`from_omniauth'app/controllers/sessi
当使用rubyselenium驱动程序驱动chrome时,我得到/home/travis/.rvm/gems/ruby-2.6.2/gems/selenium-webdriver-3.141.5926/lib/selenium/webdriver/remote/response.rb:72:in`assert_ok':sessionnot创建:Chrome版本必须在70和73之间(Selenium::WebDriver::Error::SessionNotCreatedError)如何解决这个问题?降级chrome不是我想做的事。 最佳答案
我找不到任何使用Rack::Session::Cookie的简单示例,并且希望能够将信息存储在cookie中,并在以后的请求中访问它并让它过期.这些是我能找到的唯一示例:HowdoIset/getsessionvarsinaRackapp?http://rack.rubyforge.org/doc/classes/Rack/Session/Cookie.html这是我得到的:useRack::Session::Cookie,:key=>'rack.session',:domain=>'foo.com',:path=>'/',:expire_after=>2592000,:secret=