接入集团auth流程
前言
一直对集团的auth系统很感兴趣,所以这次记录下接入集团auth的流程。如果后期有时间,会补充具体的auth实现细节。
正文
一、实现思想
1. 实现思想
明确几个名词:接入方,管理方。接入方指的是:要接入auth系统的这些应用;管理方指的是:管理应用程序的地方,也就是我们的auth系统。
auth的大致的实现逻辑就是:需要进行权限验证的接入方的请求url在进行权限验证的时候把所有的验证、管理、授权操作都通过发送请求的方式来让管理方来处理。那么就可以理解为:用户有没有登录的权限,有没有某个请求的权限都是通过管理方来判断的。
具体流程图如下所示:

二、实现代码
1. url请求需要经过中间件


2. 请求中间件代码
class Authenticate
{
public function handle(Request $request, Closure $next)
{
if (!Aus::checkLogin()) {
return Aus::goLogin($request->url());
} $uri = "/".trim($request->route()->uri, "/"); if (!Aus::authorize($uri)) {
$msg = '对不起,你没有对应的权限,请联系管理员!'; if ($request->ajax()) {
$ajaxResp = json_encode(['code' => 401, 'message' => $msg], JSON_UNESCAPED_UNICODE);
return response($ajaxResp, 200);
} return response("<h2>$msg</h2>", 401);
} return $next($request);
}
}
class AuthenticateService
{
private static $notAuthList = ["/"]; /**
* 验证登陆
*
* @return bool
*/
public static function checkLogin()
{
if (Config::get('auto_auth.ignore_auth', false)) {
return true;
}
return Session::has('user') ? true : false;
} /**
* 鉴权
* @param $uri
* @return bool
*/
public static function authorize($uri)
{
if (Config::get('auto_auth.ignore_auth', false)) {
return true;
} // 不用校验的URI
if (in_array($uri, self::$notAuthList)) {
return true;
} if (!Session::has('user.permissions')) {
return false;
}
if (!Session::has('user.token')) {
return false;
} $user = Session::get('user'); foreach ($user['permissions'] as $permission) {
$permission = rtrim($permission, '/');
if ($permission) {
$permission = '#'.$permission.'#';
if (@preg_match($permission, $uri)) {
return true;
}
}
} return false;
} /**
* 通过Auth系统登陆
*
* @param string $token
*
* @return array|bool
*/
public static function getUserByToken($token)
{
$ssoCheckUrl = Config::get('auto_auth.url') . '/sso/checktoken?token=' . $token;
$httpResponse = file_get_contents($ssoCheckUrl);
$content = []; if ($httpResponse) {
$content = json_decode($httpResponse, true);
}
if (isset($content['code']) && 0 == $content['code']) {
$allPermissions = array_get($content, 'data.permissions', []);
$permissions = [];
$baseRole = null;
foreach ($allPermissions as $permission) {
if ($permission['app_key'] == Config::get('auto_auth.app_key')) {
$permissions[] = $permission['regex'];
}
} $userInfo = [
'user_id' => $content['data']['account'],
'username' => $content['data']['name'],
'email' => $content['data']['email'],
'mobile' => $content['data']['mobile'],
'ttl' => $content['data']['ttl'],
'token' => $token,
'permissions' => $permissions,
'baseRule' => !is_null($baseRole) ?? 0,
];
session(['user' => $userInfo]); return $userInfo;
} return false;
} /**
* 跳转登陆页面
* @param $targetUrl
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public static function goLogin($targetUrl)
{
$params = [
'tarurl' => $targetUrl,
'app_key' => Config::get('auto_auth.app_key'),
]; $params_str = http_build_query($params);
$login_url = Config::get('auto_auth.url') . Config::get('auto_auth.api_list.login') . '?' . $params_str;
return redirect($login_url);
} /**
* 登出
* @param $targetUrl
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public static function goLogout($targetUrl)
{
$params = [
'tarurl' => $targetUrl,
'app_key' => Config::get('auto_auth.app_key'),
'token' => Session::get('user.token'),
]; $params_str = http_build_query($params);
$logout_url = Config::get('auto_auth.url') . Config::get('auto_auth.api_list.login') . '?' . $params_str;
Session::forget('user'); return redirect($logout_url);
} // 获取当前登录用户信息
public static function getAuthUser()
{
if (!self::checkLogin()) {
return [];
}
return Session::get('user');
} /**
* 获取当前登录用户的ID
*/
public static function getLoginUserId()
{
return array_get(Session::get('user'), 'user_id', 0);
} /**
* 获取当前登录用户的ID
*/
public static function getLoginMobile()
{
return array_get(Session::get('user'), 'mobile', 0);
} /**
* 获取登陆用户的邮箱
*/
public static function getLoginEmail()
{
return array_get(Session::get('user'), 'email', '');
} /**
* 获取当前登录用户的名字
*/
public static function getLoginUserName()
{
return array_get(Session::get('user'), 'username', 'admin');
} /**
* 获取当前登录用户权限列表(正则表达式)
* @return array
*/
public static function getUserPermissions()
{
$user = self::getAuthUser();
return array_get($user, 'permissions', []);
} /**
* 获取授权菜单
* @param $list
* @return mixed
*/
public static function getAuthMenu($list) {
if (Config::get('auto_auth.ignore_auth', false)) {
return $list;
} $result = [];
$parentCount = [];
foreach ($list as $item) {
//父级菜单直接通过
if ($item['pid'] == 0) {
$result[] = $item;
} else {
//有权限的子菜单
if (self::authorize($item['auth_url'])) {
$result[] = $item;
//标记被使用到的父级菜单
$parentCount[$item['pid']] = 1;
}
}
} //去掉没有用过的父级菜单
foreach ($result as $k => $item) {
if ($item['pid'] == 0 && empty($parentCount[$item['id']])) {
unset($result[$k]);
}
} return $result;
}
}
Route::group(['prefix' => '/sso', 'namespace' => 'Auth'], function () {
Route::get('/login', 'SsoController@login');
Route::get('/jump', 'SsoController@jump');
Route::get('/logout', 'SsoController@logout');
if(env('APP_ENV', 'local') == 'local') {
Route::get('/mockLogin', 'SsoController@mockLogin');
}
});
class SsoController extends Controller
{
/**
* 登陆
*/
public function login(Request $request)
{
$validator = Validator::make(
$request->all(), [
'action' => 'required|in:login,logout',
'token' => 'required',
]
); if ($validator->fails()) {
return -1;
} if ('login' != $request->get('action')) {
return -2;
}
$token = $request->get('token'); $user = Aus::getUserByToken($token); if (empty($user)) {
return -2;
} return response($request->callback . "('" . Config::get('auto_auth.app_key') . "')")
->withCookie('token', $request->token, 10000000)
->header('p3p', 'CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
} public function logout(Request $request)
{
$url = $request->root();
return Aus::goLogout($url);
} public function jump() {
return Aus::goLogin("http://".$_SERVER['HTTP_HOST']."/index/home");
} public function mockLogin(Request $request) { $userInfo = [
'user_id' => array_get($request, 'user_id'),
'username' => array_get($request, 'username', ''),
'email' => array_get($request, 'email', ''),
'mobile' => array_get($request, 'mobile', ''),
'ttl' => 3600*100,
];
session(['user' => $userInfo]);
}
}
AUTO_AUTH_IGNORE_AUTH=false
#AUTO_AUTH_URL=
AUTO_AUTH_URL=
AUTO_AUTH_APP_URL=
AUTO_AUTH_APP_KEY=
AUTO_AUTH_API_LIST_LOGIN=
3. 后台配置项目相关内容


三、总结
总的流程是:
添加中间件代码 => 修改中间件涉及的代码 => 修改env配置 => 后端配置
注意:测试环境可用dev4
后序
不积跬步无以至千里,不积小流无以成江海
接入集团auth流程的更多相关文章
- php接入支付宝的流程
php接入支付宝的流程写在这里供像我一样的小白参考. 1.首先要有一个创建一个应用(选好自己想要的功能,关于支付的功能,貌似都需要签约) 2.下载SDK&Dome(网址https://doc. ...
- php接入支付宝的流程(转载)
php接入支付宝的流程写在这里供像我一样的小白参考. 1.首先要有一个创建一个应用(选好自己想要的功能,关于支付的功能,貌似都需要签约) 2.下载SDK&Dome(网址https://doc. ...
- 公众号H5页面接入微信登录流程
公众号H5页面接入微信登录流程 源码地址 https://gitee.com/szxio/h5_weixin 起步 首先创建一个项目,我们采用uni-app来作为我们的前端框架 环境安装 全局安装vu ...
- dotnet 为大型应用接入 ApplicationStartupManager 启动流程框架
对于大型的应用软件,特别是客户端应用软件,应用启动过程中,需要执行大量的逻辑,包括各个模块的初始化和注册等等逻辑.大型应用软件的启动过程都是非常复杂的,而客户端应用软件是对应用的启动性能有所要求的,不 ...
- APP工程师接入Telink Mesh流程 -3
加密是为了使网络更加的安全.健壮,若由于login.加密等流程 严重影响了 开发进程,也可以通过 修改SDK 固件 将login.加密 环节取消 1.发送数据.接受数据加密,解密去掉 mesh_sec ...
- 使用Tornado异步接入第三方(支付宝)支付
目前国内比较流行的第三方支付主要有支付宝和微信支付,博主最近研究了下如何用Python接入支付宝支付,这里我以Tornado作为web框架,接入支付宝构造支付接口. 使用Tornado异步接入支付宝支 ...
- 如何推进企业流程体系建设?_K2 BPM
推进全集团统一的流程体系为什么比想象的难? 很多企业在推进全集团的流程管理过程中,经常会有一种“望山跑死马”的感觉.“各成员公司都建立起与集团公司统一的流程管理体系”,看似很简单一件事情,但没有经过良 ...
- H5测试点总结-UI测试、功能测试、兼容性测试、体验相关(弱网、资源、手机操作等)、安全性测试、性能测试
一.概述 1.1 什么是H5 H5 即 HTML5,是最新的 Web 端开发语言版本,现如今,大多数手机 APP 页面会用 H5 实现,包括 PC Web 站点也会用它开发实现.所以 Web 的通用测 ...
- [转]10+倍性能提升全过程--优酷账号绑定淘宝账号的TPS从500到5400的优化历程
摘要: # 10+倍性能提升全过程--优酷账号绑定淘宝账号的TPS从500到5400的优化历程 ## 背景说明 > 2016年的双11在淘宝上买买买的时候,天猫和优酷土豆一起做了联合促销,在天猫 ...
随机推荐
- JS判断页面是否为浏览器当前页
function currentPage() { var hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in do ...
- docker search - 搜寻镜像
使用docker search 命令可以搜索docker hub官方仓库中的镜像. # docker search --help Usage: docker search [OPTIONS] TERM ...
- matlab 中figure的图像 抗锯齿
linehandle = plot(xxxxxx); set( linehandle, 'linesmoothing', 'on' );
- iptable防火墙原理
iptable防火墙原理 简介 Linux 2.0 ipfs/firewalld Linux 2.2 ipchain/firewall Linux 2.4 iptables/netfilter (ip ...
- C#使用反射机制获取类信息
1.用反射动态创建类实例,并调用其公有成员函数. //新建一个类库项目,增加一个GetSum方法. using System; namespace ClassLibrary1 { publi ...
- element-ui升级笔记;echarts图表100px问题
1.element-ui的2.7以后的版本支持树形table结构的数据,考虑优化一下表格,就升级了,但是升级到最新的版本2.12发现table都出不来了,于是降级到2.7.目前功能正常,2.12的bu ...
- HTTP/1.1-HTTP/2.0-HTTP/3.0-HTTPS
HTTP/1.1 网上关于HTTP/1.1的讨论多是基于RFC2616文档,而IETF已更新了HTTP/1.1并将其分为六个部分,使协议变得更简单易懂,对老版本RFC2616中模糊不清的部分做了解释 ...
- Vim搜索关键字
有以下两种方法 Method 1:/content 默认从上往下查找 只读模式下输入 /content 后回车 按 n 向下查找 按N 向上查找 Method 2:?content 默认从下往上查找 ...
- ini文件多了个dos的^M结尾符号,导致linux下脚本程序不能运行
[omcr@lnlte2dmr-tdl legacy]$ cat -A ums_del_mr_files_cfg.ini MrFileDiskMountPoint=/home^M$ MrFileDis ...
- 【30分钟学完】canvas动画|游戏基础(extra1-1):美图我也行
前言 本文是接续系列教程的extra1,主要是介绍颜色系统在canvas中的应用. 本来是与extra1一起成文的,因为segmentfault莫名其妙的字数限制bug只能分割放送了. canvas操 ...
