Maison  >  Article  >  cadre php  >  Explication détaillée de la méthode d'authentification unique Laravel

Explication détaillée de la méthode d'authentification unique Laravel

WBOY
WBOYavant
2022-06-15 11:45:122735parcourir

Cet article vous apporte des connaissances pertinentes sur laravel, qui présente principalement des problèmes liés à l'authentification unique signifie que dans plusieurs systèmes d'applications, les utilisateurs n'ont besoin de se connecter qu'une seule fois pour accéder à tous. système de candidature de confiance mutuelle. J’espère qu’il sera utile à tout le monde.

Explication détaillée de la méthode d'authentification unique Laravel

【Recommandation connexe : tutoriel vidéo laravel

Single Sign On (Single Sign On), appelé SSO, est l'une des solutions d'intégration commerciale d'entreprise les plus populaires. La définition du SSO est que dans plusieurs systèmes d'applications, les utilisateurs n'ont besoin de se connecter qu'une seule fois pour accéder à tous les systèmes d'applications mutuellement fiables.

Après vous être connecté au système principal, vous accéderez au sous-système. Vous n'avez pas besoin de vous connecter pour accéder au backend du sous-système (prenez laravel-admin comme exemple)

Configuration du système principal. : connexion mono-utilisateur laravel

La configuration du sous-système est la suivante

Connexion

EncoreAdminControllersAuthController.php modification, vous pouvez séparer la méthode sans modifier le fichier source.

Ajouter du code

use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Redis;

Modifier la méthode postLogin()

if ($this->guard()->attempt($credentials, $remember)) {
     
     // return $this->sendLoginResponse($request);//此注释修改为以下
     return $this->sendLoginResponse($request,$credentials);
}

Modifier la méthode sendLoginResponse()

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);
        
    }

Ajouter la méthode createtoken()

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);
    }

Tout d'abord, après une connexion réussie, obtenez l'horodatage actuel et interrogez l'utilisateur via IP, l'heure Nom d'utilisateur et chaîne antivol unique uniquement, seule la clé peut être n'importe quel caractère, effectuer le cryptage MD5 et obtenir TOKEN. Ensuite, nous stockons l'horodatage et le jeton que nous venons d'obtenir dans Redis, et la Redis Key est concaténée avec le nom d'utilisateur dans la chaîne, ce qui est pratique pour le middleware suivant TOKEN Vérifiez, puis nous stockons les informations utilisateur dans Session MD5 加密, 得到 TOKEN 。然后我们将刚刚得到的时间戳以及token, 存入 Redis, Redis Key 为字符串拼接上username, 方便后面中间件的 TOKEN 验证, 然后我们把用户信息存入 Session . 上边与主系统区别,为Redis的 rediskey不同,目的主系统账号被顶掉的情况不影响分系统登录

创建中间件

中间件通俗点说就是访问方法时,会提前验证中间件的内容,验证通过可以访问要访问方法

命令创建中间件

// 项目根目录运行
    php artisan make:middleware SsoMiddleware

上面个命令会在 app/Http/Middleware下面生成一个SsoMiddleware.php 文件, 将中间件添加到app/Http/ Kernel.php

protected $routeMiddleware = []中添加以下

'SsoMiddleware' => \App\Http\Middleware\SsoMiddleware::class,

现在到中间件中写程序 app/Http/Middleware/SsoMiddleware.php, 在文件中有 handle 方法, 我们在这个方法中写逻辑.

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');
            }
            
        }
    }

上面中间件之中做的事情是: 获取用户存在 Session 之中的数据作为第一重判断, 如果通过判断, 进入第二重判断, 先获取token 以及存入 Redis 的时间戳, 取出来安顺序和IP,username,time,onlykey,MD5加密, 加密后和客户端得到的tokenLa différence entre ce qui précède et le système principal est que le rediskey de Redis est différent. supprimé n'affectera pas la connexion au sous-système

Création d'un middleware

En termes simples, lors de l'accès à une méthode, le contenu du middleware sera vérifié à l'avance. Après vérification, vous pourrez accéder à la méthode à laquelle accéder.

Commande pour créer un middleware

public function clearsession(Request $request){
        $prefix=config('admin.route.prefix');
       return  redirect('/'.$prefix.'/auth/logout');
}
La commande ci-dessus sera dans Générez un fichier <code>SsoMiddleware.php sous app/Http/Middleware et ajoutez le middleware à l'application. /Http/ Kernel.php

protected $routeMiddleware = [ ] Ajoutez ce qui suit

'middleware' => ['web', 'admin','SsoMiddleware'],
Maintenant, écrivez le programme dans le middleware app/Http/Middleware/SsoMiddleware.php . Il y a une méthode handle dans le fichier. Nous sommes dans cette méthode Write logic.

<?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']);
    }
    
}
Ce que fait le middleware ci-dessus est : obtenir les données dans la Session de l'utilisateur. le premier niveau de jugement. S'il réussit le jugement, entrez dans le deuxième niveau de jugement, obtenez d'abord le jeton et l'horodatage stocké dans Redis est retiré et chiffré avec IP, nom d'utilisateur, heure, clé uniquement, MD5 et crypté avec le jeton Comparaison <p>La différence avec le système principal est que le lien dans le sous-système a un nom d'utilisateur pour activer la signature unique. activé. Si la vérification du jeton réussit, vous pouvez vous connecter au sous-système sans connaître le mot de passe</p> <p><a href="https://www.php.cn/course/list/23.html" target="_blank">L'erreur/invite est un style d'invite et vous devez cliquer ici pour télécharger la méthode Clear clearsession()</a>rrreee. </p>🎜Groupe de routage🎜🎜🎜Nous avons fini d'écrire la logique. La dernière étape consiste à contrôler chaque étape de l'opération de connexion de l'utilisateur entre nos propres mains.🎜🎜Modifier la configuration /admin.php🎜rrreee. 🎜Il existe également une méthode de sous-système d'authentification unique du système principal en une étape🎜rrreee🎜Accès à ssoinfo après la liaison de routage🎜🎜Connexion réussie ! ! ! 🎜🎜【Recommandation associée : 🎜tutoriel vidéo laravel🎜】🎜

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer