Home >PHP Framework >Laravel >Detailed explanation of laravel single sign-on method
This article brings you relevant knowledge about laravel, which mainly introduces the related issues about single sign-on. Single sign-on means that in multiple application systems, users only need You can access all mutually trusted application systems by logging in once. Let’s take a look at them together. I hope it will be helpful to everyone.
[Related recommendations: laravel video tutorial]
Single Sign On (Single Sign On), referred to as SSO, is a comparative One of the popular enterprise business integration solutions. The definition of SSO is that in multiple application systems, users only need to log in once to access all mutually trusted application systems.
After logging in to the main system, you will jump to the sub-system without logging in to access the backend of the sub-system (take laravel-admin as an example)
Main system configuration: laravel single User login
The sub-system configuration is as follows
Login
Encore\Admin\Controllers\AuthController.php modification , you can separate the method without modifying it on the source file.
Add code
use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Redis;
Modify postLogin() method
if ($this->guard()->attempt($credentials, $remember)) { // return $this->sendLoginResponse($request);//此注释修改为以下 return $this->sendLoginResponse($request,$credentials); }
Modify sendLoginResponse() method
protected function sendLoginResponse(Request $request,$credentials) { admin_toastr(trans('admin.login_successful')); $request->session()->regenerate(); // return redirect()->intended($this->redirectPath()); // 制作 token return $this->createtoken($credentials,$request); }
Add createtoken() method
protected function createtoken($credentials,$request){ //相同局域网下多设备通用token if(!Redis::get('STRING_SINGLETOKEN_MAJOR1_'. $credentials['username'])){ $time = time(); // 当前 time 存入 Redis Redis::set('STRING_SINGLETOKEN_MAJOR1_'. $credentials['username'], $time); } //局域网不通用 但设备使用 注释上边多设备使用 // $time = time(); $time=Redis::get('STRING_SINGLETOKEN_MAJOR1_'. $credentials['username']); // md5 加密 $singleToken = md5($request->getClientIp() . $credentials['username'] . $time .'cjfdm'); Redis::set('SINGLETOKEN_MAJOR1_'. $credentials['username'],$singleToken); // 用户信息存入 Session Session::put('user_login', $credentials['username']); return redirect()->intended($this->redirectPath())->withCookie('SINGLETOKEN', $singleToken); }
After successfully logging in first, get the current timestamp, query the user's username and the unique anti-theft string onlykey through IP, time, onlykey can be any character, perform MD5
encryption, and get TOKEN
. Then we store the timestamp and token we just obtained into Redis
, and Redis Key
is spliced into the string with username to facilitate TOKEN
verification by the middleware later. Then we store the user information in Session
. The difference between the above and the main system is that the rediskey of Redis is different. The purpose of the main system account being deleted will not affect the sub-system login
Create middleware
Middleware in layman’s terms means that when accessing a method, the content of the middleware will be verified in advance. If the verification is passed, the method to be accessed can be accessed
Command to create middleware
// 项目根目录运行 php artisan make:middleware SsoMiddleware
The above command will generate a SsoMiddleware.php
file under app/Http/Middleware
, and add the middleware Go to app/Http/ Kernel.php
protected $routeMiddleware = [] and add the following
'SsoMiddleware' => \App\Http\Middleware\SsoMiddleware::class,
Now go to the middleware and write the program app/Http/ Middleware/SsoMiddleware.php
, there is a handle
method in the file, we write logic in this method.
public function handle($request, Closure $next) { $prefix=config('admin.route.prefix'); $array=['/'.$prefix.'/auth/login','/'.$prefix.'/auth/logout','/'.$prefix.'/auth/clearsession']; $username= Session::get('user_login'); $info=array(); $info['time']=$request->input('time'); $info['username']=$request->input('username'); $info['token']=$request->input('token'); if(!$info['username']||!$username){ $url=$request->getRequestUri(); if(in_array($url,$array)){ return $next($request); exit; } } if ($username) { // 获取 Cookie 中的 token $singletoken = Redis::get('SINGLETOKEN_MAJOR1_'.$username); if ($singletoken) { // 从 Redis 获取 time $redisTime = Redis::get('STRING_SINGLETOKEN_MAJOR1_'. $username); // 重新获取加密参数加密 $ip = $request->getClientIp(); $secret = md5($ip . $username . $redisTime.'cjfdm'); if ($singletoken != $secret) { // 记录此次异常登录记录 // \DB::table('data_login_exception')->insert(['guid' => $userInfo->guid, 'ip' => $ip, 'addtime' => time()]); // 清除 session 数据 // abort('404','你可能来到了没有知识的荒漠'); // return redirect('/'.$prefix.'/auth/logout'); // $request->session()->invalidate(); $data = [ 'message' => '您的帐号在另一个地点登录..!', 'url' => '/'.$prefix.'/auth/clearsession', 'jumpTime' => 5, 'status' => 'error' ]; //显示模板及数据 return response()-> view('errors/Prompt',compact('data')); } return $next($request); } else { return redirect('/'.$prefix.'/auth/logout'); } } else { if ($info['username']) { $singletoken = $info['token']; $redisTime =$info['time']; $username=$info['username']; $ip = $request->getClientIp(); $secret = md5($ip . $username . $redisTime.'cjfdm'); if ($singletoken != $secret) { return redirect('/'.$prefix.'/auth/logout'); }else{ $remember = $request->get('remember', false); $credentials['username']=$info['username']; if (Auth::guard('admin')->attempt($credentials, $remember)) { // return $this->sendLoginResponse($request); $request=Request(); return $this->sendLoginResponse($request,$credentials); } } }else{ return redirect('/'.$prefix.'/auth/logout'); } } }
What the above middleware does is: Get the user existence The data in Session
is used as the first level of judgment. If it passes the judgment, it enters the second level of judgment. First obtain the token
and the timestamp stored in Redis
. Take out the security sequence and encrypt it with IP, username, time, onlykey, MD5. After encryption, compare it with the token
obtained by the client. The difference from the main system is that the link in the sub-system has username and can open a single point Log in. If the token verification is successful, you can log in to the subsystem without knowing the password.
The errors/Prompt is a prompt style and you need to click here to download
Clear clearsession() method
public function clearsession(Request $request){ $prefix=config('admin.route.prefix'); return redirect('/'.$prefix.'/auth/logout'); }
Routing group
We have finished writing the logic. The last step is to control every step of the user's operation after logging in. Here we need the routing group.
Modify config/admin.php
'middleware' => ['web', 'admin','SsoMiddleware'],
There is also one step to the main system single sign-in sub-system method
<?php namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Session; use Illuminate\Support\Facades\Redis; class SsoController extends Controller { public function ssoinfo(Request $request){ $data=array(); $data['username']=Session::get('user_login'); $data['time']=Redis::get('STRING_SINGLETOKEN_MAJOR_'. $data['username']); $data['token']=Redis::get('SINGLETOKEN_MAJOR_'.$data['username']); return redirect()->intended("http://activeadmin.rongdeji.com/zhuanshu/auth/login?username=".$data['username'].'&&time='.$data['time'].'&&token='.$data['token']); } }
Access ssoinfo after routing binding
Successful login! ! !
[Related recommendations: laravel video tutorial]
The above is the detailed content of Detailed explanation of laravel single sign-on method. For more information, please follow other related articles on the PHP Chinese website!