前言

一直对集团的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. vue项目中引入循环执行setInterval或者requestAnimationFrame的用法等

    项目中循环计时处理某些方法的情况还是比较常见的,一般会用setInterval来处理,但是这个方法会似的页面卡顿等使用体验不好. 所以就使用浏览器提供的requestAnimationFrame方法, ...

  2. Java面试总结 -2018(补录)

    参考详见:https://blog.csdn.net/jackfrued/article/details/44921941 https://blog.csdn.net/jackfrued/articl ...

  3. IDEA启动软件可以选择进入项目而不是直接进入项目

    1.File--->Settings 2.Appearance & behavior --->System Settings --->Reopen last project ...

  4. ipc - System V 进程间通信机制

    SYNOPSIS 总览 # include <sys/types.h> # include <sys/ipc.h> # include <sys/msg.h> # ...

  5. Linux下安装升级python

    本文主要是参考帖子,感谢这位博主,我主要是对相关操作进行补充和说明. 本文主要是在linux(centos)下安装Python3.7.1 1.下载安装Python-3.7.1 1) 下载Python- ...

  6. Python控制语句执行流程

    if语句: if<条件>:#条件之后必须有“:”.  <语句> if语句的三元运算符: <表达式1>if<条件>else<表达式2>:其语义 ...

  7. puppet自动化安装服务

    puppet自动化部署 主机环境: server(master)端:172.25.7.1(server1.example.com) client(agent)端:172.25.7.2 172.25.7 ...

  8. centos7部署nagios(二)

    一.Nagios简介 分类: 监控 undefined Nagios是一款开源的电脑系统和网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系 ...

  9. string::front

    char& front(); const char& front() const;功能:返回string对象的首个字符,可以改变它的值 #include <string># ...

  10. CentOS7安装并使用Ceph

    1.准备工作1.1 安装配置NTP官方建议在所有 Ceph 节点上安装 NTP 服务(特别是 Ceph Monitor 节点),以免因时钟漂移导致故障. ln -sf /usr/share/zonei ...