前言

一直对集团的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流程的更多相关文章

  1. php接入支付宝的流程

    php接入支付宝的流程写在这里供像我一样的小白参考. 1.首先要有一个创建一个应用(选好自己想要的功能,关于支付的功能,貌似都需要签约) 2.下载SDK&Dome(网址https://doc. ...

  2. php接入支付宝的流程(转载)

    php接入支付宝的流程写在这里供像我一样的小白参考. 1.首先要有一个创建一个应用(选好自己想要的功能,关于支付的功能,貌似都需要签约) 2.下载SDK&Dome(网址https://doc. ...

  3. 公众号H5页面接入微信登录流程

    公众号H5页面接入微信登录流程 源码地址 https://gitee.com/szxio/h5_weixin 起步 首先创建一个项目,我们采用uni-app来作为我们的前端框架 环境安装 全局安装vu ...

  4. dotnet 为大型应用接入 ApplicationStartupManager 启动流程框架

    对于大型的应用软件,特别是客户端应用软件,应用启动过程中,需要执行大量的逻辑,包括各个模块的初始化和注册等等逻辑.大型应用软件的启动过程都是非常复杂的,而客户端应用软件是对应用的启动性能有所要求的,不 ...

  5. APP工程师接入Telink Mesh流程 -3

    加密是为了使网络更加的安全.健壮,若由于login.加密等流程 严重影响了 开发进程,也可以通过 修改SDK 固件 将login.加密 环节取消 1.发送数据.接受数据加密,解密去掉 mesh_sec ...

  6. 使用Tornado异步接入第三方(支付宝)支付

    目前国内比较流行的第三方支付主要有支付宝和微信支付,博主最近研究了下如何用Python接入支付宝支付,这里我以Tornado作为web框架,接入支付宝构造支付接口. 使用Tornado异步接入支付宝支 ...

  7. 如何推进企业流程体系建设?_K2 BPM

    推进全集团统一的流程体系为什么比想象的难? 很多企业在推进全集团的流程管理过程中,经常会有一种“望山跑死马”的感觉.“各成员公司都建立起与集团公司统一的流程管理体系”,看似很简单一件事情,但没有经过良 ...

  8. H5测试点总结-UI测试、功能测试、兼容性测试、体验相关(弱网、资源、手机操作等)、安全性测试、性能测试

    一.概述 1.1 什么是H5 H5 即 HTML5,是最新的 Web 端开发语言版本,现如今,大多数手机 APP 页面会用 H5 实现,包括 PC Web 站点也会用它开发实现.所以 Web 的通用测 ...

  9. [转]10+倍性能提升全过程--优酷账号绑定淘宝账号的TPS从500到5400的优化历程

    摘要: # 10+倍性能提升全过程--优酷账号绑定淘宝账号的TPS从500到5400的优化历程 ## 背景说明 > 2016年的双11在淘宝上买买买的时候,天猫和优酷土豆一起做了联合促销,在天猫 ...

随机推荐

  1. 用python 获取照片的Exif 信息(获取拍摄设备,时间,地点等信息)

    第一步:先安装 pip install exifread 第二部:上代码 import exifread import requests class PhotoExifInfo(): def __in ...

  2. 6.纯css绘制叮当猫

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  3. 修改MIGO或者ML81N产生的会计凭证项目文本增强

    在程序:MM07MFF9_F_BELEG_ERGAENZEN下做隐式增强

  4. nodejs express 部署

    一.express 4.x版本之前 全局安装express 命令是 npm install express -g express 4.x版本之后 全局安装express 命令是 npm install ...

  5. python 文件夹压缩

    import os import zipfile def zipDir(dirpath,outFullName): """ 压缩指定文件夹 :param dirpath: ...

  6. jquery 保留两位小数

    jquery 通过 toFixed 保留两位小数 <script> var num = 12.21654; console.log(num.toFixed(2)) </script& ...

  7. python基础练习题7

    1.创建Person类,属性有姓名.年龄.性别,创建方法personInfo,打印这个人的信息2.创建Student类,继承Person类,属性有学院college,班级class,重写父类perso ...

  8. Shiro(一)

    1 权限管理 1.1 什么是权限管理? 基本上涉及到用户参与的系统都要进行权限管理,权限管理属于系统安全的范畴,权限管理实现对用户访问权限的控制,按照安全规则或者安全策略控制用户可以访问而且只能访问自 ...

  9. create-react-app踩坑记

    前言 哇,不的不说这个react 这个脚手架create-react-app脚确实有很多问题,哈哈,下面来看看吧有哪些坑: 引用sass或者less 记得16年还是几年是不支持sass,和less的, ...

  10. 12. ClustrixDB 为容错和可用性分配磁盘空间

    集群必须包含足够的空闲磁盘空间,以便从节点或区域故障中自动恢复.要计算在发生故障后仍然允许ClustrixDB完全重新保护数据的情况下可以使用的最大磁盘空间量,可以使用以下公式: 最大磁盘利用率% = ...