接入集团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在淘宝上买买买的时候,天猫和优酷土豆一起做了联合促销,在天猫 ...
随机推荐
- [.net core]6.launchSettings.json,调试配置
展开properties, 双击查看内容, { "iisSettings": { "windowsAuthentication": false, "a ...
- [转载]Ubuntu下apache的安装与配置
原文地址:https://blog.csdn.net/gatieme/article/details/53025505 1 安装apache 在 Ubuntu 上安装 Apache,有两种方式 使用源 ...
- 响应式前端框架Bootstrap系列(11)分页
分页功能已经封装成一个独立的js文件,也是用bs完成的,名称为bootstrap-paginator.js. 使用前先导入文件 : <script src="../libs/boots ...
- vscode如何使用?常用插件有哪些?
vscode下载 官网下载:https://code.visualstudio.com/ 一.汉化中文(官方下载默认为英文,英文好的小伙伴可直接跳过这步) 点击插件按钮搜索 Chinese, 在弹出的 ...
- 如何将本地的一个新项目上传到GitHub上新建的仓库中去
1:我们需要先创建一个本地的版本库(其实也就是一个文件夹).直接右击新建文件夹,或者右击打开Git bash命令行窗口通过命令mkdir来创建(mkdir 文件名). 进入这个文件夹的根目录,选中目录 ...
- 集合类Hash Set,LinkedHashSet,TreeSet
集合(set)是一个用于存储和处理无重复元素的高效数据结构.映射表(map)类似于目录,提供了使用键值快速查询和获取值的功能. HashSet类是一个实现了Set接口的具体类,可以使用它的无参构造方法 ...
- Centos7安装升级Ruby和集群搭建参考
安装升级Ruby参考:https://blog.csdn.net/qq_26440803/article/details/82717244 集群搭建参考:https://www.cnblogs.com ...
- 用 C++ 模板元编程实现有限的静态 introspection
C++ 中的奇技淫巧大部分来源于模板技术,尤其是模版元编程技术(Template Meta-Programming, TMP).TMP 通过将一部分计算任务放在编译时完成,不仅提高了程序的性能,还能让 ...
- Django的MTV模型
MTV模型 Django框架的设计模式借鉴了MVC框架的思想,也是分成三部分,来降低各个部分之间的耦合性. MTV框架是Django的框架,三部分为: Model Template(模板) View ...
- Linux--目录管理与文件管理--02
******Linux目录结构与目录管理******* 一.Linux目录结构: 1.目录创建规则:FHS文件系统层次化标准 指定了Linux操作系统的哪些目录是一定要具备的 2.目录的结构 树形结构 ...