php+ajax实现跨域单点登录
之前我们在《SSO单点登录三种情况的实现方式详解》中介绍过跨域单点登录的原理。这里向大家介绍利用php和ajax具体实现单点登录。
在本次示例中我们需要两个站点:
www.onmpw.com
www.onmpw1.com
当然还有一个验证系统
www.SSOsite.com
为了实现单点登录。首先,我们需要将要设置两个站点使其共享session。至于如何共享session,可以参考《PHP集群session共享》这篇文章。这里我们就不做详细的介绍了。
假设我们已经设置了二者可以共享session了。下面我们就来介绍具体实现的流程。
第一部分
下面我们用文字来描述该过程
·浏览器请求onmpw的需要验证的页面。
·通过ajax请求SSOsite系统,查看是否存在SSOsite站点的cookie信息,如果不存在则通知浏览器需要进行登录。
·浏览器接收到需要登录的信息后请求onmpw的登录页面(当然有的系统是统一使用SSOsite的登录系统,那就需要浏览器再去请求SSOsite的登录页面了)。
·提交登录信息到onmpw系统。onmpw系统通过curl技术将登录信息发送给SSOsite系统进行验证。
curl_setopt($ch, CURLOPT_URL, "www.SSOsite.com/?c=Auth&a=authUser");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('username'=>$username,'password'=>$password));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
$res = json_decode($data);
·SSOsite验证成功以后,生成token,并将用户信息连同生成的token一并返回给onmpw系统。
const chars = 'abcdefgABCDEFG012hijklmnHIJKLMN3456opqrstOPQRST789UVWXYZuvwxyz';
static public function str_random(){
//随机生成token串
$chars = self::chars;
$token = '';
for($i = 0; $i < 5; $i++){
$str = substr($chars,0,mt_rand(0, strlen($chars)-1));
$token .= $str.$chars[mt_rand(0, strlen($str)-1)];
}
$token = md5($token);
return $token;
}
·onmpw接收到SSOsite返回的验证成功的信息以后,将用户信息写入浏览器的cookie中。最后将登录成功的信息响应给浏览器。
setcookie('userid',$res->userid,null,'/'); //设置本站点cookie
·然后浏览器再次通过ajax将得到的token发送给SSOsite。
checkToken:function(args){
$.ajax({
url:Onmpw_SSO.Configure.SSO_Server+'/?c=Auth&a=checkToken',
xhrFields: {withCredentials: Onmpw_SSO.Configure.Cross_Domain},
dataType:'json',
type:'post',
data:{token:args.token,userid:args.userid},
success:function(data){
args.Suc();
},
error:function(err){
console.log(err);
}
})
},
SSOsite得到token以后将token存入浏览器端cookie和session中。
public function checkToken(){
$this->authUrl();
session_start();
if(isset($_POST['token'])){
setcookie('usertoken',$_POST['token'],null);
setcookie('userid',$_POST['userid'],null);
$_SESSION['token'] = $_POST['token'];
echo json_encode(array('auth'=>'SUC'));
}
}
注意在浏览器通过ajax向SSOsite发送请求的情况下需要设置CORS(跨域资源共享)。
private function authUrl(){
$origin = $_SERVER['HTTP_ORIGIN'];
if (in_array($origin, $this->urlArr)) {
header("Access-Control-Allow-Origin:" . $origin);
header("Access-Control-Allow-Credentials: true ");
}else{
echo "error!";
exit;
}
}
设置完成以后,返回浏览器登录成功。
第二部分
下面我们用文字描述该过程
·浏览器请求onmpw的需要验证的页面。
·通过ajax带着cookie信息请求SSOsite系统。SSOsite系统在cookie中提取用户token。然后再次生成一个临时token存入session中,其键名为用户token。最后通知浏览器该用户已经登录成功,并且将临时token一并返回给浏览器。
$tmptoken = \Common::str_random();
$_SESSION[$_SESSION['token']] = $tmptoken;
·浏览器接收到临时token,然后再次通过ajax将临时token发送给SSOsite进行验证。SSOsite验证完成临时token,将session中的临时token销毁。并且得到自己的sessionId返回给浏览器。
public function authToken(){
$this->authUrl();
session_start();
$tmptoken = $_POST['tmptoken'];
if($tmptoken == $_SESSION[$_SESSION['token']]){
unset($_SESSION[$_SESSION['token']]);
echo json_encode(array('auth'=>'SUC','userid'=>$_COOKIE['userid'],'sessionId'=>session_id()));
}else{
echo json_encode(array('auth'=>'FAIL'));
}
}
·浏览器收到SSOsite返回的sessionId以后,将sessionId发送给onmpw。onmpw系统接收到浏览器带来的sessionId以后,用此sessionId来初始化自身的session。将先前存入浏览器cookie中的用户信息存入session中并且销毁cookie信息(当然在session开启之后,我们先检查session中是否存在用户信息,如果不存在则将cookie中的用户信息存入session,并销毁cookie)。
$sessionId = $_POST['sessionId'];
session_id($sessionId);
session_start();
if(!isset($_SESSION['userid'])){
$userid = $_COOKIE['userid'];
setcookie('userid',"",time()-3600,'/');
$_SESSION['userid'] = $userid;
}
·这样浏览器就可以知道用户信息存在,进行相应的操作。在第一部分步骤完成以后,用户也可以请求onmpw1。其步骤是和第二部分描述的相同。
至此,通过php和ajax实现跨域单点登录的流程已经全部完成。其中有一部分核心代码,可以点此查看完整代码。希望本文对大家有所帮助。
相关文章
Get the last inserted ID using PHP MySQLi function
发布时间:2025/04/22 浏览次数:100 分类:MySQL
-
This article briefly introduces the PHP mysqli() function and demonstrates how to use it to get the last inserted ID from a MySQL database. PHP mysqli() Function It is an extended version of the MySQL driver called mysqli and is typically u
Deleting all rows in a MySQL database using phpMyAdmin
发布时间:2025/04/22 浏览次数:153 分类:MySQL
-
We will learn the best way to delete all rows in a database using DELETE. We will explore phpMyAdmin the command to delete rows from a given table. MySQL DELETE We will also learn the difference between the DELETE , , DROP and TRUNCATE comm
Loop PHP MySQLi Get Array Function
发布时间:2025/04/21 浏览次数:105 分类:MySQL
-
MySQLi fetch function is used to access data from the database server. After fetching the data, you can also iterate over it MySQLi with queries. In this article, we will see mysqli_fetch_array() the use of functions and methods to iterate
AJAX calls in Node.js
发布时间:2025/04/17 浏览次数:103 分类:Node.js
-
Representational State Transfer is abbreviated as REST . An API or Web API (Application Programming Interface) that complies with the restrictions and limitations of the REST architectural style and allows interaction with RESTful web servi
Check if a Post exists in PHP
发布时间:2025/04/13 浏览次数:171 分类:PHP
-
PHP $_POST is a super global variable that can contain key-value pairs of HTML form data submitted through the post method. We will learn different ways to check $_POST if a and contains some data in this article. These methods will use iss
PHP with Ajax
发布时间:2025/04/13 浏览次数:140 分类:PHP
-
We will use PHP and ajax by printing a simple sum of two numbers 2 and . Also, print a php array in JSON. 3 object We will also use PHP with ajax by getting the HTML formatted output from the number division in PHP. Printing simple addition
Store Div Id in PHP variable and pass it to JavaScript
发布时间:2025/04/13 浏览次数:52 分类:PHP
-
This article shows you how to div id store a in a PHP variable and pass it to JavaScript code. We will answer the following questions. What is div id ? How to div id store in a PHP variable? How to pass variables to JavaScript code? Let’s
Returns the article tag with ID from the action page
发布时间:2025/04/13 浏览次数:80 分类:PHP
-
Let's say you're in a login form and you enter the wrong information; in this case, you probably want to go back to the login page. PHP has a built-in function header() to redirect a page to a specific page. But what if the login page is at
Switching PHP versions on Ubuntu
发布时间:2025/04/13 浏览次数:79 分类:PHP
-
Different tasks may require running multiple versions of PHP. You may need to switch PHP versions by running two sites on the same server or testing older versions of code using outdated methods. We can switch PHP versions on Ubuntu using t