单点登陆实战,重新认识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

相关文章
|
6月前
|
XML 存储 安全
【揭秘SAML协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略Saml协议的奥秘,告别SSO的迷茫与困惑
SAML(Security Assertion Markup Language)是由OASIS制定的基于XML的开放标准。它用于在身份提供者(IdP)和服务提供者(SP)之间交换身份验证和授权数据,从而支持跨域单点登录,提高身份认证和授权管理的安全性和效率。
479 2
【揭秘SAML协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略Saml协议的奥秘,告别SSO的迷茫与困惑
|
3月前
|
存储 JSON JavaScript
震撼!Cookie、Session、Token、JWT 终极对决:揭开 Web 认证的神秘面纱!
【8月更文挑战第13天】Web 开发中,Cookie、Session、Token 和 JWT 常混淆。Cookie 是服务器给客户端的小信息片,如登录状态,每次请求都会返回。Session 则是服务器存储的用户数据,通过 Session ID 追踪。Token 类似通行证,证明客户端身份且可加密。JWT 是结构化的 Token,含头部、载荷及签名,确保数据完整性和安全性。
68 4
|
6月前
|
存储 监控 安全
金石推荐 | 【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
金石推荐 | 【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
123 1
|
6月前
|
JSON 安全 算法
【揭秘OIDC协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略OIDC协议的奥秘,告别SSO的迷茫与困惑
【揭秘OIDC协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略OIDC协议的奥秘,告别SSO的迷茫与困惑
238 0
|
6月前
|
存储 安全 Java
【揭秘OAuth协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略OAuth协议的奥秘,告别SSO的迷茫与困惑
在现代的网站中,我们经常会遇到需要用户登录的情况。然而,直接要求用户注册可能会显得繁琐,导致用户的流失。为了解决这个问题,网站可以采用OAuth授权机制。通过与像GitHub或其他第三方网站的认证授权合作,网站可以获取用户的相关信息,避免了繁琐的注册过程。
88 0
【揭秘OAuth协议 — Java安全认证框架的核心基石】 从初识到精通,带你领略OAuth协议的奥秘,告别SSO的迷茫与困惑
|
存储 监控 安全
【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
传统上,企业应用程序在公司网络中部署和运行。为了获取有关用户的信息,如用户配置文件和组信息,这些应用程序中的许多都是为与公司目录(如Microsoft Active Directory)集成而构建的。更重要的是,通常使用目录存储和验证用户的凭据。例如,如果您使用在本地运行的SharePoint和Exchange,则您的登录凭据就是您的Active Directory凭据。
330 1
【分布式技术专题】「单点登录技术架构」一文带领你好好认识以下Saml协议的运作机制和流程模式
|
XML API 网络架构
API接口的技术的概念
当今互联网技术的发展越来越快,越来越多的网站和应用程序需要获取外部数据来提供更好的服务和用户体验,这就需要使用API接口。本文将会对API接口的概念、类型以及如何调用API接口进行简要介绍。
|
存储 缓存 UED
接口测试开发之:一篇搞懂 Cache、Cookie及Session的爱恨情仇
接口测试开发之:一篇搞懂 Cache、Cookie及Session的爱恨情仇
172 1
接口测试开发之:一篇搞懂 Cache、Cookie及Session的爱恨情仇
实战:第二十章:社交类用户登录功能
实战:第二十章:社交类用户登录功能
实战:第二十章:社交类用户登录功能