前言
好的技术方案,是根据业务的变化,慢慢的迭代而来的。
文章以登录态这个技术点为核心,分为三个阶段叙述登陆态在不同业务需求下不同的实现方式。
一、1:1 阶段
业务
一台服务器,一个客户端(一般是指PC端)阶段。不需要考虑集群、多端的情形,只有一个要求,就是快速实现业务需求,让产品尽快上线试水业务的可行性。
关键点
快速实现产品
解决
用cookie->session会话方案保存登录态。
二、1:N 阶段
业务
跌跌撞撞、打磨完产品的基础功能之后,从1:1阶段,进入第二阶段,即一台服务器,多个客户端(安卓、IOS APP,H5)发展。
关键点
多客户端
解决
继续沿用cookie->session会话方案保存登录态,但要做如下的修改。
- cookie作用域
php在入口文件,做设置如下:
ini_set('session.cookie_path', '/');
ini_set('session.cookie_domain','.baidu.com');
如果涉及到子域跨域调用,例如:我服务端的接口二级域名是 server.baidu.com,而调用接口的地方,是 app.baidu.com,则需要在 server.baidu.com 的入口处做如下herder声明,表示允许指定的域名安全访问。
header("Access-Control-Allow-Credentials:true");
header('Access-Control-Allow-Methods:POST,GET');
header("Access-Control-Allow-Origin: https://app.baidu.com");
- 客户端调用要传入cookie-id
我们产品有3个客户端(h5、安卓、ios),在h5和ios下,完成以上的操作,能够成功的获取到登陆态,但是在安卓客户端,会出现登陆态丢失的问题。需要客户端在调用服务端接口的时候,显示的传入cookid,来标识对话这是一个完整的会话来解决问题。
三、N:N 阶段
业务: 随着业务的发展,单台服务器不够支撑业务,就会出现服务器集群,同时又拥有多个客户端,业务进入第三阶段,即N:N阶段。
session原理
###session会话文件默认路径
session.save_path = "/tmp"
根据php.ini的以上配置节点,会在服务器指定的路径上生成对应的临时会话文件。
原理图
当业务处在第一阶段和第二阶段的时候,在一台服务器上进行访问、登录操作,默认的sesion配置不会出现问题,如果集群环境下。
- 会出现这种情况:
我的登陆操作在A服务器完成,临时会话文件 保存在A服务器,下一步访问个人中心,是到达了B服务器,所以导致登陆态丢失。
用户访问图例
解决
方案1. 共享session
共享session我介绍的是将session存储到redis中。
- 增加一台redis服务器(192.168.0.110);
- PHP默认情况下是不支持对Redis的操作,安装第三方的扩展,使其支持对Redis的操作;
- 将session存储到redis中,修改PHP配置文件php.ini将session存储到redis中;
- 打开php.ini,需要修改的有这两项:
session.save_handler 和 session.save_path。
session.save_handler = Redis
//Redis不需要密码验证
session.save_path = “tcp://192.168.0.110:6379”
//Redis 需要密码验证
//session.save_path = “tcp://192.168.0.110:6379?auth=password”
服务器A和服务器B都做按照以上步骤操作。经过以上步骤,对于session的所有信息都保存到了Redis中,从而实现了session的共享。
方案2. token
jwt官网 - JSON Web Tokens - jwt.io
使用成型的 jwt 解决方案。该方案是另外一种思路,下一篇文章,详细写。
不同的阶段,根据业务的侧重点,对应着不同的解决方案。
以上,谢谢。
网友评论