单点登陆实战,重新认识session

简介: 前言:首先介绍下项目背景,我经手的项目呢,是一个音乐网站,看上去是一个网站,实际上是三个项目,首先是一个基于onethink开发的音乐分享平台,第二个是基于客客族的一个众包类型的平台,第三个是基于ecshop的商城。

前言:

首先介绍下项目背景,我经手的项目呢,是一个音乐网站,看上去是一个网站,实际上是三个项目,首先是一个基于onethink开发的音乐分享平台,第二个是基于客客族的一个众包类型的平台,第三个是基于ecshop的商城。三个项目的分别使用三个二级域名。各自代码数据库独立。我接到的需求的就是,让用户只需一个账号就能在三个网站中都能使用。就是用上去像一个网站就对了。

当时想了很多种思路,我觉得主要的难点在于,网站已经是一个线上运营的项目了,已经有一定的用户。各个项目数据表的设计也不相同,对用户密码的加密方式也不同。更厉害的是其中有个项目的用户表是一张大表,里面有很多字段,记录着用户的各种信息。

步骤:

解决分两步走,无论用什么方法解决,必须实现的功能就两个,那就是:

  1. 单点注册
  2. 单点登陆

1.单点注册

首先,我们抛开老用户不管,首先新用户,一来注册。肯定只需一个地方注册就不用在别的地方注册了。那么我的思路是关闭二三站的注册,将全部的注册引导至第一站来注册。当第一站的代码执行到注册成功,写入数据表的步骤时,我添加两个curl带上用户的注册信息,访问我在二三站写好了的注册接口

 //注册成功
//注册成功要调用一个大注册方法
$bigData['username'] = $username;
$bigData['password'] = $password;
$bigData['email'] = $email;
//加入token,提高安全性
$bigData['token']=md5('xxxxxxxx');
$taskUrl = 'http://task.56sing.com?xxxxxxxxxx.php';
$shopUrl = 'http://shop.56sing.com/xxxxxxxxx.php';
//封装的curl方法,传入url和数据
$this->bigRegister($taskUrl, $bigData);
$this->bigRegister($shopUrl, $bigData);

由于curl是模拟浏览器访问url,所以也不存在跨域的问题,前端的控制台,也没办法捕获这次调用。我自我感觉还是比较安全的

2站和3站的接口接收到传来的数据,直接调用自己的注册方法就可完成注册了。这样一以来,用户就可以使用童颜的账号密码登陆三个站点了。

当时感觉还行啊,感觉这个思路走的通,所以我就打算继续用curl传账号密码,完成单点登陆。当代码写好了后,发现傻逼了。于是我冷静下来重新思考了的网站的登陆原理。

我开始回忆起来最初学习登录的思路,如下图

初学登陆

乍一看好像也没什么大问题,我通过curl将账号密码传入接口,接口收到账号密码后调用登陆方法,验证通过的话就写入session。没毛病啊?
这时候,我又有一个疑问了,当我把账号密码传入接口,通过验证完成登陆时,我的浏览器并没有访问2,3站的页面。那么当我去访问它的页面时。网站怎么知道我是我呢?(这个问题给了我灵感)

最后我将注意力集中到了session身上。我回忆起来,其实每个session在生成的时候,都会一个session_id存入cookie里。

  • 这个session_id就像是数组的键一样,有一个对应的值,这个值就存在服务器的内存中
那么登陆的原理就是:

我们结合http协议来看这个问题,
当我们向服务器发起请求,并带上账号密码,服务器接收到了账号密码,并验证。如果通过,就把登陆状态的值记录在session中,然后返回一个登陆成功的页面或者一个json。就在返回的时候携带了session_id 存入用户的浏览器中。这样,这个session登陆信息就只有刚刚登录的那个人的浏览器才能访问,就知道是谁登录,谁没登录了。

那么弄清了原理之后我们就想了一个思路(是一个二逼思路)


二逼思路

好了大家看一看就行了哈。我就不介绍了。

经过一番思考后,和网上查资料,我发现了一个问题,curl只是一个模拟浏览器访问一个url。并没有真正的浏览器存在。那么也就没存cookie的说法。那么我又将目光移向了ajax跨域请求
下面是行的通的思路(敲黑板,划重点)

可行的思路.png

看到这里,细心的朋友肯定发现了,我说这么多,还是没有说怎么搞定cookie的session_id嘛
下面介绍如何共享session_id的,我们从两个方面来说

1. 浏览器端(客户端)

当我发送加密账号密码时,我会带上当前浏览器中储存的cookie

   $.ajax({
        //登录接口的url
        url:data.loginData.task.url,
        type: 'POST',
        //异步请求
        async:true,
        //通过设置 withCredentials: true ,发送Ajax时,Request header中便会带上 Cookie 信息
        xhrFields:{
        withCredentials:true
        },
       //账号密码
       data:{
        'sing56':data.loginData.task.sing56,
        'sing':data.loginData.task.sing
       },
      success:function (response) {

       },
      error:function (reason) {
        console.dir(reason);
       }
   });
2. 服务器端

首先我们要解决允许跨域请求,大家都是知道的,随后能就要允许携带cookie了

//获取请求来源地址
$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
//设置允许请求的数组
$arrAllow=['http://www.56sing.com','http://shop.56sing.com'];
//判断是否在允许请求数组中
if (in_array($origin,$arrAllow)) {
    //允许请求
    header('Access-Control-Allow-Origin:'.$origin);
}
//允许请求的方式为post
header('Access-Control-Allow-Methods:POST');
//允许携带cookie
header('Access-Control-Allow-Credentials:true');
header('Access-Control-Allow-Headers:x-requested-with,content-type');

对应客户端的 xhrFields.withCredentials: true 参数
服务器端通过在响应 header 中设置 Access-Control-Allow-Credentials = true 来运行客户端携带证书式访问。通过对 Credentials 参数的设置,就可以保持跨域 Ajax 时的 Cookie。
这里需要注意的是:
服务器端 Access-Control-Allow-Credentials = true时,参数Access-Control-Allow-Origin 的值不能为 '*'

那么这样做的效果就是
当我在第一站登录,调用2站的登陆接口时会传递一个session_id

image.png

当我进入第二站时,账号已经自动登陆,并且当前cookie中存储的session_id,正是我们传递过来的那一个

image.png

好了,本次单点登陆实战的介绍了就写到这里了,如果有什么地方不对,希望大神指正.谢谢。
参考三位大神的博客,在这感谢了:
kangjianrong
sueris
guodengh

相关文章
|
29天前
|
XML 存储 安全
【揭秘SAML协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略Saml协议的奥秘,告别SSO的迷茫与困惑
SAML(Security Assertion Markup Language)是由OASIS制定的基于XML的开放标准。它用于在身份提供者(IdP)和服务提供者(SP)之间交换身份验证和授权数据,从而支持跨域单点登录,提高身份认证和授权管理的安全性和效率。
223 2
【揭秘SAML协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略Saml协议的奥秘,告别SSO的迷茫与困惑
|
29天前
|
JSON 安全 算法
【揭秘OIDC协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略OIDC协议的奥秘,告别SSO的迷茫与困惑
【揭秘OIDC协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略OIDC协议的奥秘,告别SSO的迷茫与困惑
65 0
|
29天前
|
存储 监控 安全
金石推荐 | 【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
金石推荐 | 【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
85 1
|
29天前
|
存储 安全 Java
【揭秘OAuth协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略OAuth协议的奥秘,告别SSO的迷茫与困惑
在现代的网站中,我们经常会遇到需要用户登录的情况。然而,直接要求用户注册可能会显得繁琐,导致用户的流失。为了解决这个问题,网站可以采用OAuth授权机制。通过与像GitHub或其他第三方网站的认证授权合作,网站可以获取用户的相关信息,避免了繁琐的注册过程。
56 0
【揭秘OAuth协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略OAuth协议的奥秘,告别SSO的迷茫与困惑
|
存储 监控 安全
【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
传统上,企业应用程序在公司网络中部署和运行。为了获取有关用户的信息,如用户配置文件和组信息,这些应用程序中的许多都是为与公司目录(如Microsoft Active Directory)集成而构建的。更重要的是,通常使用目录存储和验证用户的凭据。例如,如果您使用在本地运行的SharePoint和Exchange,则您的登录凭据就是您的Active Directory凭据。
298 1
【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
实战:第二十章:社交类用户登录功能
实战:第二十章:社交类用户登录功能
实战:第二十章:社交类用户登录功能
|
存储 缓存 UED
接口测试开发之:一篇搞懂 Cache、Cookie及Session的爱恨情仇
接口测试开发之:一篇搞懂 Cache、Cookie及Session的爱恨情仇
144 1
接口测试开发之:一篇搞懂 Cache、Cookie及Session的爱恨情仇
|
存储 Web App开发 搜索推荐
浅谈电商网站开发中用户会话管理机制的设计和实现原理(二)
笔者由于工作需要,最近对国内外两款知名的电商网站的用户会话管理(User Session Management) 的实现机制做了一些调研,这里把我学习到的一些知识分享给各位同行,希望起到抛砖引玉的作用。
146 0
浅谈电商网站开发中用户会话管理机制的设计和实现原理(二)
|
Web App开发 存储 前端开发
浅谈电商网站开发中用户会话管理机制的设计和实现原理(一)
笔者由于工作需要,最近对国内外两款知名的电商网站的用户会话管理(User Session Management) 的实现机制做了一些调研,这里把我学习到的一些知识分享给各位同行,希望起到抛砖引玉的作用。
178 0
浅谈电商网站开发中用户会话管理机制的设计和实现原理(一)