搜索
首页后端开发php教程laravel 5.2 用户注册和登录

laravel5.2 验证有所改动,增加了一个叫guard的东西,这个东西主要是负责检查用户的session之类的

原文有提到: https://laravel.com/docs/5.2/authentication#introduction

At its core, Laravel’s authentication facilities are made up of “guards” and “providers”. Guards define how users are authenticated for each request. For example, Laravel ships with a session guard which maintains state using session storage and cookies and a token guard, which authenticates users using a “API token” that is passed with each request.

这个命令会自动创建一些验证相关的文件resources/views/auth 和resources/views/layouts,不过我们暂时先不用,先理解过程。

php artisan make:auth

先提前布置一下路由表

app/Http/routes.phpRoute::group(['middleware' => ['web']], function () {    Route::resource('/articles','ArticlesController');    Route::get('auth/login','Auth\AuthController@getLogin'); //打开登录页面,用get    Route::post('auth/login','Auth\AuthController@postLogin'); //提交request给login页面的postLogin方法,其实是给Auth\AuthController的postLogin    Route::get('auth/register','Auth\AuthController@getRegister'); //类似    Route::post('auth/register','Auth\AuthController@postRegister');//类似    Route::get('auth/logout','Auth\AuthController@getLogout'); //logout单独独立出来,也是类似的方式使用//        Route::get('auth/logout',function(){//            Auth::logout();//        });});

需要说明一下:

1. 上面这些在laravel 5.2里面都是要包含在web这个中间件的[‘middleware’ => [‘web’],除了csrf之外,还有一些验证的逻辑会有关联。

2. login 和 register是在“保护”内的,而logout则不是,具体可以看AuthController.php,主要是因为logout比较随意,也不能用session来限制其访问

3. 上面这些路由都不是默认提供的,需要自己手写,主要是因为laravel 5.2开始没有提供,不过正因为这样,整个流程也比较清晰的整理出来

4. laravel这个默认登录注册是需要跟model关联的,如果model有问题,则也会影响整个过程,laravel把很多东西都封装好了,对于一般人来说,不容易知道里面的流程怎么生效的,需要不断研究学习源码才行。

这是我理解的过程图

首先看AuthController

app/Http/Controllers/Auth/AuthController.php< ?phpnamespace App\Http\Controllers\Auth;use App\User;use Validator;use App\Http\Controllers\Controller;use Illuminate\Foundation\Auth\ThrottlesLogins;use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;class AuthController extends Controller{    /*    |--------------------------------------------------------------------------    | Registration & Login Controller    |--------------------------------------------------------------------------    |    | This controller handles the registration of new users, as well as the    | authentication of existing users. By default, this controller uses    | a simple trait to add these behaviors. Why don't you explore it?    |    */    use AuthenticatesAndRegistersUsers, ThrottlesLogins;  //使用了这2个类作为主要的验证功能类,下面会说到    /**     * Where to redirect users after login / registration.     *     * @var string     */    protected $redirectTo = '/';  //这个是登录成功的重定向链接,有时候需要修改。    /**     * Create a new authentication controller instance.     *     * @return void     */    public function __construct()    {        $this->middleware($this->guestMiddleware(), ['except' => 'logout']);   //排除了logout,不在中间件保护范围内    }    /**     * Get a validator for an incoming registration request.     *     * @param  array  $data     * @return \Illuminate\Contracts\Validation\Validator     */    protected function validator(array $data)  //这里自带了一个验证逻辑,request的验证有2种方法,一种是写request文件,一种就是用validator    {        return Validator::make($data, [            'name' => 'required|max:255',            'email' => 'required|email|max:255|unique:users',            'password' => 'required|min:6|confirmed',  //默认有这些验证逻辑,这个逻辑是有讲究的,因为默认的laravel验证注册登录是会关联到这里的。        ]);    }    /**     * Create a new user instance after a valid registration.     *     * @param  array  $data     * @return User     */    protected function create(array $data)  //这个就是create,在函数体里面就是用了model的create方法,直接在数据库生成数据    {        return User::create([            'name' => $data['name'],            'email' => $data['email'],            'password' => bcrypt($data['password']),        ]);    }}

然后我们看AuthenticatesAndRegistersUsers

vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesAndRegistersUsers.php< ?phpnamespace Illuminate\Foundation\Auth;trait AuthenticatesAndRegistersUsers{    use AuthenticatesUsers, RegistersUsers {//这里是重点,使用了两个类,一个是验证用户,一个是注册用户        AuthenticatesUsers::redirectPath insteadof RegistersUsers;          AuthenticatesUsers::getGuard insteadof RegistersUsers;    }}

然后我们再看AuthenticatesUsers

因为我们在路由上写了要调用getlogin,postlogin,getregister,postregister,而AuthenticatesUsers就是主要处理getlogin,postlogin的。

vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php<?phpnamespace Illuminate\Foundation\Auth;use Illuminate\Http\Request;use Illuminate\Support\Facades\Auth;use Illuminate\Support\Facades\Lang;trait AuthenticatesUsers{    use RedirectsUsers;    /**     * Show the application login form.     *     * @return \Illuminate\Http\Response     */    public function getLogin()  //getLogin在此!    {        return $this->showLoginForm();    }    /**     * Show the application login form.     *     * @return \Illuminate\Http\Response     */    public function showLoginForm()  //其实调用这个showLoginForm    {        $view = property_exists($this, 'loginView')                    ? $this->loginView : 'auth.authenticate';        if (view()->exists($view)) {            return view($view);        }        return view('auth.login'); //看到这里可以看出,判断是否存在auth.authenticate文件,如果没有则用auth.login,这个文件其实就是views文件夹下面的blade文件,即resources/views/auth/login.blade.php    }    /**     * Handle a login request to the application.     *     * @param  \Illuminate\Http\Request  $request     * @return \Illuminate\Http\Response     */    public function postLogin(Request $request) //这里是postlogin    {        return $this->login($request);    }    /**     * Handle a login request to the application.     *     * @param  \Illuminate\Http\Request  $request     * @return \Illuminate\Http\Response     */    public function login(Request $request) //其实调用的是login    {        $this->validateLogin($request);        // If the class is using the ThrottlesLogins trait, we can automatically throttle        // the login attempts for this application. We'll key this by the username and        // the IP address of the client making these requests into this application.        $throttles = $this->isUsingThrottlesLoginsTrait();  //这个是判读用户登录的频率相关的        if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {  //这里有一个更详细的toomanylogin            $this->fireLockoutEvent($request);            return $this->sendLockoutResponse($request);        }        $credentials = $this->getCredentials($request);  //这里是用来确认用户是否登陆过,会跟remember有关,就是免登陆相关的。        if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {            return $this->handleUserWasAuthenticated($request, $throttles);        }        // If the login attempt was unsuccessful we will increment the number of attempts        // to login and redirect the user back to the login form. Of course, when this        // user surpasses their maximum number of attempts they will get locked out.        if ($throttles && ! $lockedOut) {            $this->incrementLoginAttempts($request);        }        return $this->sendFailedLoginResponse($request);    }    /**     * Validate the user login request.     *     * @param  \Illuminate\Http\Request  $request     * @return void     */    protected function validateLogin(Request $request)    {        $this->validate($request, [            $this->loginUsername() => 'required', 'password' => 'required',        ]);    }    /**     * Send the response after the user was authenticated.     *     * @param  \Illuminate\Http\Request  $request     * @param  bool  $throttles     * @return \Illuminate\Http\Response     */    protected function handleUserWasAuthenticated(Request $request, $throttles)    {        if ($throttles) {            $this->clearLoginAttempts($request);        }        if (method_exists($this, 'authenticated')) {            return $this->authenticated($request, Auth::guard($this->getGuard())->user());        }        return redirect()->intended($this->redirectPath());    }    /**     * Get the failed login response instance.     *     * @param \Illuminate\Http\Request  $request     * @return \Illuminate\Http\Response     */    protected function sendFailedLoginResponse(Request $request)    {        return redirect()->back()            ->withInput($request->only($this->loginUsername(), 'remember'))            ->withErrors([                $this->loginUsername() => $this->getFailedLoginMessage(),            ]);    }    /**     * Get the failed login message.     *     * @return string     */    protected function getFailedLoginMessage()    {        return Lang::has('auth.failed')                ? Lang::get('auth.failed')                : 'These credentials do not match our records.';    }    /**     * Get the needed authorization credentials from the request.     *     * @param  \Illuminate\Http\Request  $request     * @return array     */    protected function getCredentials(Request $request)    {        return $request->only($this->loginUsername(), 'password');    }    /**     * Log the user out of the application.     *     * @return \Illuminate\Http\Response     */    public function getLogout()    {        return $this->logout();    }    /**     * Log the user out of the application.     *     * @return \Illuminate\Http\Response     */    public function logout()    {        Auth::guard($this->getGuard())->logout();        return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');    }    /**     * Get the guest middleware for the application.     */    public function guestMiddleware()    {        $guard = $this->getGuard();        return $guard ? 'guest:'.$guard : 'guest';    }    /**     * Get the login username to be used by the controller.     *     * @return string     */    public function loginUsername()    {        return property_exists($this, 'username') ? $this->username : 'email';    }    /**     * Determine if the class is using the ThrottlesLogins trait.     *     * @return bool     */    protected function isUsingThrottlesLoginsTrait()    {        return in_array(            ThrottlesLogins::class, class_uses_recursive(static::class)        );    }    /**     * Get the guard to be used during authentication.     *     * @return string|null     */    protected function getGuard()    {        return property_exists($this, 'guard') ? $this->guard : null;    }}

然后我们再看RegistersUsers.php

这个主要处理getregister,postregister

vendor/laravel/framework/src/Illuminate/Foundation/Auth/RegistersUsers.php< ?phpnamespace Illuminate\Foundation\Auth;use Illuminate\Http\Request;use Illuminate\Support\Facades\Auth;trait RegistersUsers{    use RedirectsUsers;    /**     * Show the application registration form.     *     * @return \Illuminate\Http\Response     */    public function getRegister() //这里就是getRegister    {        return $this->showRegistrationForm();    }    /**     * Show the application registration form.     *     * @return \Illuminate\Http\Response     */    public function showRegistrationForm()  //其实调用的是他    {        if (property_exists($this, 'registerView')) {            return view($this->registerView);        }        return view('auth.register');  //看逻辑可以知道,如果没有registerView的话就用auth.register来作为注册页,原理跟login差不多    }    /**     * Handle a registration request for the application.     *     * @param  \Illuminate\Http\Request  $request     * @return \Illuminate\Http\Response     */    public function postRegister(Request $request) //这里是postRegister    {        return $this->register($request);    }    /**     * Handle a registration request for the application.     *     * @param  \Illuminate\Http\Request  $request     * @return \Illuminate\Http\Response     */    public function register(Request $request)  //其实是用他,这里有点复杂    {        $validator = $this->validator($request->all());          if ($validator->fails()) {  //会先去判断是否能够通过validator,而这个validator就是之前在AuthController.php的那个,而且这个throwValidationException(并不是在页面的显示错误的                                    //是在这里storage/logs/laravel.log            $this->throwValidationException(                $request, $validator            );        }        Auth::guard($this->getGuard())->login($this->create($request->all()));         //这里通过调用getGuard来判断是否确认写入数据库,这里首先通过create写入数据库,然后进行login登录,登录成功了,就是下面的回调页面了。好巧妙。        return redirect($this->redirectPath()); //注册成功返回的那个回调页面,也是在AuthController.php配    }    /**     * Get the guard to be used during registration.     *     * @return string|null     */    protected function getGuard()    {        return property_exists($this, 'guard') ? $this->guard : null;  //这个就是判断auth.php里的guard的。    }}

然后我们配置登录页面

resources/views/auth/login.blade.php@extends('layout.app')@section('content')    <div class="col-md-4 col-md-offset-4">        {!! Form::open(['url'=>'auth/login']) !!}  //这里跟路由表配置要相匹配,post提交到auth/login                <!--- Email Field --->        <div class="form-group">            {!! Form::label('email', 'Email:') !!}     //登录项有2个,一个是email一个是password            {!! Form::email('email', null, ['class' => 'form-control']) !!}        </div>        <!--- Password Field --->        <div class="form-group">            {!! Form::label('password', 'Password:') !!}            {!! Form::password('password', ['class' => 'form-control']) !!}        </div>        {!! Form::submit('登录',['class'=>'btn btn-primary form-control']) !!}        {!! Form::close() !!}    </div>    <ul class="list-group">   //这个代码是额外的,主要是为了看验证失败的时候的报错信息,laravel会将错误信息写到$errors里面去,所以能够在页面获取来看        @foreach($errors->all() as $error)            <li class="list-group-item list-group-item-danger">{{$error}}</li>        @endforeach    </ul>@stop

然后我们配置注册页面

这里我们有4个字段,有3个事必须的,name,password,email,因为这个对应AuthController的create方法的值,其实这个也是跟model的表有关,因为我们的user表也就是使用这3个字段来做验证的。

resources/views/auth/register.blade.php@extends('layout.app')@section('content')    <div class="col-md-4 col-md-offset-4">        {!! Form::open(['url'=>'auth/register']) !!}  //注意这里是post到auth/register                <!--- Name Field --->        <div class="form-group">            {!! Form::label('name', 'Name:') !!}                {!! Form::text('name', null, ['class' => 'form-control']) !!}        </div>        <!--- Email Field --->        <div class="form-group">            {!! Form::label('email', 'Email:') !!}            {!! Form::email('email', null, ['class' => 'form-control']) !!}        </div>        <!--- Password Field --->        <div class="form-group">            {!! Form::label('password', 'Password:') !!}            {!! Form::password('password', ['class' => 'form-control']) !!}        </div>       <!--- Password-confirm Field --->        <div class="form-group">            {!! Form::label('password_confirmation', 'Password_confirmation:') !!}  //需要注意的是,这个password_confirmation是有讲究的,如果不是这样写的话,会导致validator验证不通过            {!! Form::password('password_confirmation', ['class' => 'form-control']) !!}        </div>        {!! Form::submit('注册',['class'=>'btn btn-primary form-control']) !!}        {!! Form::close() !!}    </div>        <ul class="list-group">        @foreach($errors->all() as $error)            <li class="list-group-item list-group-item-danger">{{$error}}</li>        @endforeach    </ul>@stop

然后我们看AuthenticatesUsers.php

vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php    public function getLogout()   //这里就是getLogout    {        return $this->logout();    }    /**     * Log the user out of the application.     *     * @return \Illuminate\Http\Response     */    public function logout()  //其实是他    {        Auth::guard($this->getGuard())->logout();        return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/auth/login');          //这里需要注意的是,这里logout的重定向地址需要设置一下,默认是/但是如果/是要登录才可以看的话,那么就会出错。    }

然后我们再看AuthController.php

app/Http/Controllers/Auth/AuthController.php    protected $redirectTo = '/articles'; //刚才我们提到登录成功的重定向地址就是这个$redirectTo    protected $guard = 'web';  //这个guard是特别的,是因为laravel5.2的关系

对此官网的解释

Guard CustomizationYou may also customize the "guard" that is used to authenticate users. To get started, define a guard property on your AuthController. The value of this property should correspond with one of the guards configured in your auth.php configuration file:protected $guard = 'admin';

你要设置一个guard的值,并且要跟auth.php对应好,然后我们再看看auth.php

config/auth.php< ?phpreturn [    /*    |--------------------------------------------------------------------------    | Authentication Defaults    |--------------------------------------------------------------------------    |    | This option controls the default authentication "guard" and password    | reset options for your application. You may change these defaults    | as required, but they're a perfect start for most applications.    |    */    'defaults' => [        'guard' => 'web',  //默认指定了一个guard 是叫web的        'passwords' => 'users',    ],    /*    |--------------------------------------------------------------------------    | Authentication Guards    |--------------------------------------------------------------------------    |    | Next, you may define every authentication guard for your application.    | Of course, a great default configuration has been defined for you    | here which uses session storage and the Eloquent user provider.    |    | All authentication drivers have a user provider. This defines how the    | users are actually retrieved out of your database or other storage    | mechanisms used by this application to persist your user's data.    |    | Supported: "session", "token"    |    */    'guards' => [        'web' => [  //然后这个叫web的guard呢有driver和provider这些属性,一个是session 驱动,一个是users的provider,简单理解就是用users表和session来做guard,这个guard可以理解为校验            'driver' => 'session',            'provider' => 'users',        ],        'api' => [            'driver' => 'token',            'provider' => 'users',        ],    ],    /*    |--------------------------------------------------------------------------    | User Providers    |--------------------------------------------------------------------------    |    | All authentication drivers have a user provider. This defines how the    | users are actually retrieved out of your database or other storage    | mechanisms used by this application to persist your user's data.    |    | If you have multiple user tables or models you may configure multiple    | sources which represent each model / table. These sources may then    | be assigned to any extra authentication guards you have defined.    |    | Supported: "database", "eloquent"    |    */    'providers' => [        'users' => [  //这里再次解释了users的这个provider就是一个eloquent,就是model Users            'driver' => 'eloquent',            'model' => App\User::class,        ],        // 'users' => [        //     'driver' => 'database',        //     'table' => 'users',        // ],    ],];

注册成功后会有数据在数据库生成检查数据库

id  name    email   password    remember_token  created_at  updated_at1   123456  1239@qq.com $2y$10$EfEo1gCcK6JdwgxjqjNbK.fVZjgu7i68uKMPqNwBX9VpNVuvgthm6    wSaR4V256k4xxisbbiVNS1o9iEqwCaIDZB5Nk5YZYj5JNBENIiowTALrBNNT    2016-05-25 15:31:07 2016-05-25 15:41:53

每次登录成功都会有一个laravel_session,而guard就是校验这个东西的,判断是否能登陆之类。

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
解释负载平衡如何影响会话管理以及如何解决。解释负载平衡如何影响会话管理以及如何解决。Apr 29, 2025 am 12:42 AM

负载均衡会影响会话管理,但可以通过会话复制、会话粘性和集中式会话存储解决。1.会话复制在服务器间复制会话数据。2.会话粘性将用户请求定向到同一服务器。3.集中式会话存储使用独立服务器如Redis存储会话数据,确保数据共享。

说明会话锁定的概念。说明会话锁定的概念。Apr 29, 2025 am 12:39 AM

Sessionlockingisatechniqueusedtoensureauser'ssessionremainsexclusivetooneuseratatime.Itiscrucialforpreventingdatacorruptionandsecuritybreachesinmulti-userapplications.Sessionlockingisimplementedusingserver-sidelockingmechanisms,suchasReentrantLockinJ

有其他PHP会议的选择吗?有其他PHP会议的选择吗?Apr 29, 2025 am 12:36 AM

PHP会话的替代方案包括Cookies、Token-basedAuthentication、Database-basedSessions和Redis/Memcached。1.Cookies通过在客户端存储数据来管理会话,简单但安全性低。2.Token-basedAuthentication使用令牌验证用户,安全性高但需额外逻辑。3.Database-basedSessions将数据存储在数据库中,扩展性好但可能影响性能。4.Redis/Memcached使用分布式缓存提高性能和扩展性,但需额外配

在PHP的上下文中定义'会话劫持”一词。在PHP的上下文中定义'会话劫持”一词。Apr 29, 2025 am 12:33 AM

Sessionhijacking是指攻击者通过获取用户的sessionID来冒充用户。防范方法包括:1)使用HTTPS加密通信;2)验证sessionID的来源;3)使用安全的sessionID生成算法;4)定期更新sessionID。

PHP的完整形式是什么?PHP的完整形式是什么?Apr 28, 2025 pm 04:58 PM

文章讨论了PHP,详细介绍了其完整形式,在We​​b开发中的主要用途,与Python和Java的比较以及对初学者的学习便利性。

PHP如何处理形式数据?PHP如何处理形式数据?Apr 28, 2025 pm 04:57 PM

PHP使用$ \ _ post和$ \ _获取超级全局的php处理数据,并通过验证,消毒和安全数据库交互确保安全性。

PHP和ASP.NET有什么区别?PHP和ASP.NET有什么区别?Apr 28, 2025 pm 04:56 PM

本文比较了PHP和ASP.NET,重点是它们对大规模Web应用程序,性能差异和安全功能的适用性。两者对于大型项目都是可行的,但是PHP是开源和无关的,而ASP.NET,

PHP是对病例敏感的语言吗?PHP是对病例敏感的语言吗?Apr 28, 2025 pm 04:55 PM

PHP的情况敏感性各不相同:功能不敏感,而变量和类是敏感的。最佳实践包括一致的命名和使用对案例不敏感的功能进行比较。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具