Home >PHP Framework >Laravel >Detailed explanation of laravel single sign-on method

Detailed explanation of laravel single sign-on method

WBOY
WBOYforward
2022-06-15 11:45:122924browse

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.

Detailed explanation of laravel single sign-on method

[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[&#39;username&#39;]=Session::get(&#39;user_login&#39;);
        $data[&#39;time&#39;]=Redis::get(&#39;STRING_SINGLETOKEN_MAJOR_&#39;. $data[&#39;username&#39;]);
       
        $data[&#39;token&#39;]=Redis::get(&#39;SINGLETOKEN_MAJOR_&#39;.$data[&#39;username&#39;]);
        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!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete