HybridAuth 身份验证 cookie
HybridAuth authentication cookie
我已经尝试将 HybridAuth 实施到我现有的 Web 应用程序中,该应用程序使用经典的电子邮件+密码注册和登录,但我仍然不明白我应该如何使用 HybridAuth 对用户进行身份验证。
我现有的认证系统
在我现有的登录系统中,想要登录的注册用户将他的电子邮件和密码发送到服务器。如果电子邮件和密码正确(我没有以明文形式存储用户密码,但密码验证过程与此问题无关),服务器会创建用户加密密码的哈希值和随机密钥。此散列存储在 cookie 中,还用于创建身份验证代码,其中包含之前创建的散列、用户的电子邮件和 IP 地址都散列在一起。验证码存储在用户的session.
当登录用户尝试访问该站点时,服务器从他的 cookie 中获取散列值,将其与他的电子邮件和 IP 地址一起散列,并将其与身份验证进行比较之前存储在 session 中的代码。如果代码匹配,则用户通过身份验证,否则,用户将被重定向到登录页面。
新的 HybridAuth 系统
到目前为止,我只实现了通过 Facebook 登录。当新用户单击 "Login via Facebook" 按钮时,服务器会执行多个脚本,将用户重定向到 Facebook,以便他可以授权我的应用程序,并使用用户 facebook 个人资料中的一些信息在数据库中创建新的用户记录。至此,用户注册并登录。
当此用户尝试与我的应用交互时,我必须以某种方式验证他的身份。我使用此代码:
if ($_SESSION['facebook_connected'] == true) {
try {
// try social login
$config = PUBLIC_ROOT . 'handlers/hybridauth/config.php';
require_once(PUBLIC_ROOT . 'handlers/hybridauth/Hybrid/Auth.php');
$hybridauth = new Hybrid_Auth($config);
$adapter = $hybridauth->authenticate('Facebook');
/* check if the user is registered
*
* ...
*
*/
return true;
} catch (Exception $e) {
return false;
}
}
当此代码 returns 为真时,用户通过身份验证。
每次我使用社交身份验证向我的应用程序发送请求时,Web 浏览器都必须等待大约 1-2 秒才能收到请求的 Web page/data。当我使用邮箱+密码认证时,网页几乎是即时的。
这让我觉得 HybridAuth 每次要对用户进行身份验证时都必须与 Facebook 服务器通信,这非常慢。
我的问题是:HybridAuth 能否为通过 Facebook 登录的用户创建某种身份验证 cookie,并在他每次发送请求时安全地验证他,而无需与 Facebook 通信?
抱歉问了一个很长的问题,我想解释一下我的整个身份验证系统,因为它的整个想法可能是 wrong/insecure/outdated,我必须进行一些更改才能有效地使用 HybridAuth。
旁注:HybridAuth 文档很糟糕。
您可以使用 HybridAuth 登录用户,将信息存储在您的应用程序中,并使用该信息编写您自己的身份验证系统。
使用这种方法,HibridAuth 只需登录即可与 facebook 通信,然后您可以使用自己的系统验证用户的身份,避免无用的 facebook 连接
将此列添加到您的 mysql 用户 table
CREATE TABLE `users` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`password` VARCHAR(250) NOT NULL,
`name` VARCHAR(60) NOT NULL,
`email` VARCHAR(250) NULL DEFAULT NULL,
`mobile` VARCHAR(50) NULL DEFAULT NULL,
`active` TINYINT(4) NOT NULL DEFAULT '0',
`gender` VARCHAR(50) NOT NULL DEFAULT '0',
`img` TEXT NULL,
`date_joined` DATE NOT NULL,
`facebook` INT(11) NOT NULL DEFAULT '0',
`fidentifier` VARCHAR(500) NULL DEFAULT NULL,
`fprofileURL` VARCHAR(500) NULL DEFAULT NULL,
`fphotoURL` VARCHAR(500) NULL DEFAULT NULL,
`fdisplayName` VARCHAR(500) NULL DEFAULT NULL,
`ffirstName` VARCHAR(500) NULL DEFAULT NULL,
`flastName` VARCHAR(500) NULL DEFAULT NULL,
`fgender` VARCHAR(50) NULL DEFAULT NULL,
`flanguage` VARCHAR(50) NULL DEFAULT NULL,
`femailVerified` VARCHAR(500) NULL DEFAULT NULL,
`fcoverInfoURL` VARCHAR(800) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
然后创建 php 文件 facebook.php
<?php
include 'sql.php';
function generateRandomString($length = 10) {
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
$config = array(
"base_url" => "https://yourdomain.com/handlers/hybridauth/",
"providers" => array (
"Facebook" => array (
"enabled" => true,
"keys" => array ( "id" => "YOUR_ID", "secret" => "YOUR_SECRET" ),
"scope" => "email,public_profile",
"display" => "page"
)));
require_once( "handlers/hybridauth/Hybrid/Auth.php" );
try{
$hybridauth = new Hybrid_Auth( $config );
$adapter = $hybridauth->authenticate( "Facebook" );
$user_profile = $adapter->getUserProfile();
}
catch( Exception $e ){
$user_profile = "denied" ;
}
if ( $user_profile == "denied"){
?>
<script>
window.parent.location.href=("login.php?error=1");
</script>
<?php
}
else
{
$fidentifier= $user_profile->identifier;
$fprofileURL= $user_profile->profileURL;
$fphotoURL= $user_profile->photoURL;
$fdisplayName= $user_profile->displayName;
$ffirstName= $user_profile->firstName;
$flastName= $user_profile->lastName;
$fgender= $user_profile->gender;
$flanguage= $user_profile->language;
$femailVerified= $user_profile->emailVerified;
$fcoverInfoURL= $user_profile->coverInfoURL;
$femail= $user_profile->email;
$fphone= $user_profile->phone;
$sqlc = "SELECT * FROM users WHERE fidentifier='$fidentifier' AND facebook=1";
$rs_result = $conn->query($sqlc);
if ($rs_result->num_rows == 1){
$row = $rs_result->fetch_assoc();
$_SESSION["user_id"] = $row["id"];
?>
<script>
window.parent.location.href=("profile.php");
</script>
<?php
}
else
{
$sqlc1 = "SELECT * FROM users WHERE (email='$femailVerified' OR email='$femail') AND facebook=0";
$rs_result1 = $conn->query($sqlc1);
if ($rs_result1->num_rows ==1){
$row1 = $rs_result1->fetch_assoc();
$ssid=$row1["id"];
$sql4 = "UPDATE users SET
fidentifier='$fidentifier',
fprofileURL='$fprofileURL',
fdisplayName='$fdisplayName',
name='$fdisplayName',
ffirstName='$ffirstName',
flastName='$flastName',
fgender='$fgender',
gender='$fgender',
email='$femail',
femailVerified='$femailVerified',
mobile='$fphone',
fcoverInfoURL='$fcoverInfoURL',
img='$fphotoURL',
active=1,
facebook=1
WHERE id=$ssid";
if ($conn->query($sql4) === TRUE) {
$_SESSION["user_id"] = $row1["id"];
?>
<script>
window.parent.location.href=("profile.php");
</script>
<?php
} else {
echo "Error: " . $sql4 . "<br>" . $conn->error;
}
}
else
{
$password=generateRandomString();
$sqlee = "INSERT INTO users (fidentifier,fprofileURL,fdisplayName,name,ffirstName,flastName,fgender,gender,email,femailVerified,mobile,fcoverInfoURL,img,active,facebook,password,date_joined)
VALUES ('$fidentifier','$fprofileURL','$fdisplayName','$fdisplayName','$ffirstName','$flastName',
'$fgender','$fgender','$femail','$femailVerified','$fphone','$fcoverInfoURL','$fphotoURL',1,1,'$password',NOW())";
if ($conn->query($sqlee) === TRUE) {
$lastid = $conn->insert_id;
$_SESSION["user_id"] = $lastid;
?>
<script>
window.parent.location.href=("profile.php");
</script>
<?php
}
else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
}
}
}
?>
然后像这样在您的页面中调用 $_SESSION["user_id"]
<?php
if ($_SESSION["user_id"] != ""){$suserid=$_SESSION["user_id"];}else{$suserid="";}
?>
当你需要用户登录时,你可以使用类似这样的东西
<?php
if ($suserid !=""){
//do this like a login user
}
if ($suserid ==""){
echo "login to site by facebook <a href='facebook.php' >from here</a>";
}
?>
编辑:
别忘了更改:
include 'sql.php';
// 到您的 mysql 连接页面
"base_url" => "https://yourdomain.com/handlers/hybridauth/",
// 到您的域 hybridauth 文件夹
"keys" => array ( "id" => "YOUR_ID", "secret" => "YOUR_SECRET" ),
// YOUR_ID 和 YOUR_SECRET
好的,所以您登录用户的策略是检查密码和电子邮件是否正确,然后让它们保持在会话中。使用社交登录,您应该检查电子邮件是否正确 - 如果正确:
- 检索用户记录(如果他是第一次登录,您可能需要在检索之前创建一个新用户)
- 与普通登录相同(将电子邮件和 ip 哈希放入会话中并与之前的身份验证代码进行比较)
所有请求都应作为普通请求处理,并且仅在首次身份验证时与社交提供者进行交互。
我已经尝试将 HybridAuth 实施到我现有的 Web 应用程序中,该应用程序使用经典的电子邮件+密码注册和登录,但我仍然不明白我应该如何使用 HybridAuth 对用户进行身份验证。
我现有的认证系统
在我现有的登录系统中,想要登录的注册用户将他的电子邮件和密码发送到服务器。如果电子邮件和密码正确(我没有以明文形式存储用户密码,但密码验证过程与此问题无关),服务器会创建用户加密密码的哈希值和随机密钥。此散列存储在 cookie 中,还用于创建身份验证代码,其中包含之前创建的散列、用户的电子邮件和 IP 地址都散列在一起。验证码存储在用户的session.
当登录用户尝试访问该站点时,服务器从他的 cookie 中获取散列值,将其与他的电子邮件和 IP 地址一起散列,并将其与身份验证进行比较之前存储在 session 中的代码。如果代码匹配,则用户通过身份验证,否则,用户将被重定向到登录页面。
新的 HybridAuth 系统
到目前为止,我只实现了通过 Facebook 登录。当新用户单击 "Login via Facebook" 按钮时,服务器会执行多个脚本,将用户重定向到 Facebook,以便他可以授权我的应用程序,并使用用户 facebook 个人资料中的一些信息在数据库中创建新的用户记录。至此,用户注册并登录。
当此用户尝试与我的应用交互时,我必须以某种方式验证他的身份。我使用此代码:
if ($_SESSION['facebook_connected'] == true) {
try {
// try social login
$config = PUBLIC_ROOT . 'handlers/hybridauth/config.php';
require_once(PUBLIC_ROOT . 'handlers/hybridauth/Hybrid/Auth.php');
$hybridauth = new Hybrid_Auth($config);
$adapter = $hybridauth->authenticate('Facebook');
/* check if the user is registered
*
* ...
*
*/
return true;
} catch (Exception $e) {
return false;
}
}
当此代码 returns 为真时,用户通过身份验证。
每次我使用社交身份验证向我的应用程序发送请求时,Web 浏览器都必须等待大约 1-2 秒才能收到请求的 Web page/data。当我使用邮箱+密码认证时,网页几乎是即时的。
这让我觉得 HybridAuth 每次要对用户进行身份验证时都必须与 Facebook 服务器通信,这非常慢。
我的问题是:HybridAuth 能否为通过 Facebook 登录的用户创建某种身份验证 cookie,并在他每次发送请求时安全地验证他,而无需与 Facebook 通信?
抱歉问了一个很长的问题,我想解释一下我的整个身份验证系统,因为它的整个想法可能是 wrong/insecure/outdated,我必须进行一些更改才能有效地使用 HybridAuth。
旁注:HybridAuth 文档很糟糕。
您可以使用 HybridAuth 登录用户,将信息存储在您的应用程序中,并使用该信息编写您自己的身份验证系统。
使用这种方法,HibridAuth 只需登录即可与 facebook 通信,然后您可以使用自己的系统验证用户的身份,避免无用的 facebook 连接
将此列添加到您的 mysql 用户 table
CREATE TABLE `users` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`password` VARCHAR(250) NOT NULL,
`name` VARCHAR(60) NOT NULL,
`email` VARCHAR(250) NULL DEFAULT NULL,
`mobile` VARCHAR(50) NULL DEFAULT NULL,
`active` TINYINT(4) NOT NULL DEFAULT '0',
`gender` VARCHAR(50) NOT NULL DEFAULT '0',
`img` TEXT NULL,
`date_joined` DATE NOT NULL,
`facebook` INT(11) NOT NULL DEFAULT '0',
`fidentifier` VARCHAR(500) NULL DEFAULT NULL,
`fprofileURL` VARCHAR(500) NULL DEFAULT NULL,
`fphotoURL` VARCHAR(500) NULL DEFAULT NULL,
`fdisplayName` VARCHAR(500) NULL DEFAULT NULL,
`ffirstName` VARCHAR(500) NULL DEFAULT NULL,
`flastName` VARCHAR(500) NULL DEFAULT NULL,
`fgender` VARCHAR(50) NULL DEFAULT NULL,
`flanguage` VARCHAR(50) NULL DEFAULT NULL,
`femailVerified` VARCHAR(500) NULL DEFAULT NULL,
`fcoverInfoURL` VARCHAR(800) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
然后创建 php 文件 facebook.php
<?php
include 'sql.php';
function generateRandomString($length = 10) {
$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
$config = array(
"base_url" => "https://yourdomain.com/handlers/hybridauth/",
"providers" => array (
"Facebook" => array (
"enabled" => true,
"keys" => array ( "id" => "YOUR_ID", "secret" => "YOUR_SECRET" ),
"scope" => "email,public_profile",
"display" => "page"
)));
require_once( "handlers/hybridauth/Hybrid/Auth.php" );
try{
$hybridauth = new Hybrid_Auth( $config );
$adapter = $hybridauth->authenticate( "Facebook" );
$user_profile = $adapter->getUserProfile();
}
catch( Exception $e ){
$user_profile = "denied" ;
}
if ( $user_profile == "denied"){
?>
<script>
window.parent.location.href=("login.php?error=1");
</script>
<?php
}
else
{
$fidentifier= $user_profile->identifier;
$fprofileURL= $user_profile->profileURL;
$fphotoURL= $user_profile->photoURL;
$fdisplayName= $user_profile->displayName;
$ffirstName= $user_profile->firstName;
$flastName= $user_profile->lastName;
$fgender= $user_profile->gender;
$flanguage= $user_profile->language;
$femailVerified= $user_profile->emailVerified;
$fcoverInfoURL= $user_profile->coverInfoURL;
$femail= $user_profile->email;
$fphone= $user_profile->phone;
$sqlc = "SELECT * FROM users WHERE fidentifier='$fidentifier' AND facebook=1";
$rs_result = $conn->query($sqlc);
if ($rs_result->num_rows == 1){
$row = $rs_result->fetch_assoc();
$_SESSION["user_id"] = $row["id"];
?>
<script>
window.parent.location.href=("profile.php");
</script>
<?php
}
else
{
$sqlc1 = "SELECT * FROM users WHERE (email='$femailVerified' OR email='$femail') AND facebook=0";
$rs_result1 = $conn->query($sqlc1);
if ($rs_result1->num_rows ==1){
$row1 = $rs_result1->fetch_assoc();
$ssid=$row1["id"];
$sql4 = "UPDATE users SET
fidentifier='$fidentifier',
fprofileURL='$fprofileURL',
fdisplayName='$fdisplayName',
name='$fdisplayName',
ffirstName='$ffirstName',
flastName='$flastName',
fgender='$fgender',
gender='$fgender',
email='$femail',
femailVerified='$femailVerified',
mobile='$fphone',
fcoverInfoURL='$fcoverInfoURL',
img='$fphotoURL',
active=1,
facebook=1
WHERE id=$ssid";
if ($conn->query($sql4) === TRUE) {
$_SESSION["user_id"] = $row1["id"];
?>
<script>
window.parent.location.href=("profile.php");
</script>
<?php
} else {
echo "Error: " . $sql4 . "<br>" . $conn->error;
}
}
else
{
$password=generateRandomString();
$sqlee = "INSERT INTO users (fidentifier,fprofileURL,fdisplayName,name,ffirstName,flastName,fgender,gender,email,femailVerified,mobile,fcoverInfoURL,img,active,facebook,password,date_joined)
VALUES ('$fidentifier','$fprofileURL','$fdisplayName','$fdisplayName','$ffirstName','$flastName',
'$fgender','$fgender','$femail','$femailVerified','$fphone','$fcoverInfoURL','$fphotoURL',1,1,'$password',NOW())";
if ($conn->query($sqlee) === TRUE) {
$lastid = $conn->insert_id;
$_SESSION["user_id"] = $lastid;
?>
<script>
window.parent.location.href=("profile.php");
</script>
<?php
}
else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
}
}
}
?>
然后像这样在您的页面中调用 $_SESSION["user_id"]
<?php
if ($_SESSION["user_id"] != ""){$suserid=$_SESSION["user_id"];}else{$suserid="";}
?>
当你需要用户登录时,你可以使用类似这样的东西
<?php
if ($suserid !=""){
//do this like a login user
}
if ($suserid ==""){
echo "login to site by facebook <a href='facebook.php' >from here</a>";
}
?>
编辑:
别忘了更改:
include 'sql.php';
// 到您的 mysql 连接页面
"base_url" => "https://yourdomain.com/handlers/hybridauth/",
// 到您的域 hybridauth 文件夹
"keys" => array ( "id" => "YOUR_ID", "secret" => "YOUR_SECRET" ),
// YOUR_ID 和 YOUR_SECRET
好的,所以您登录用户的策略是检查密码和电子邮件是否正确,然后让它们保持在会话中。使用社交登录,您应该检查电子邮件是否正确 - 如果正确:
- 检索用户记录(如果他是第一次登录,您可能需要在检索之前创建一个新用户)
- 与普通登录相同(将电子邮件和 ip 哈希放入会话中并与之前的身份验证代码进行比较)
所有请求都应作为普通请求处理,并且仅在首次身份验证时与社交提供者进行交互。