laravel 5.2 用户注册和登录

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

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

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.phpmiddleware($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.phpshowLoginForm();    }    /      * 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.phpshowRegistrationForm();    }    /      * 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')        {!! Form::open(['url'=>'auth/login']) !!}  //这里跟路由表配置要相匹配,post提交到auth/login            {!! Form::label('email', 'Email:') !!}     //登录项有2个,一个是email一个是password            {!! Form::email('email', null, ['class' => 'form-control']) !!}            {!! Form::label('password', 'Password:') !!}            {!! Form::password('password', ['class' => 'form-control']) !!}        {!! Form::submit('登录',['class'=>'btn btn-primary form-control']) !!}        {!! Form::close() !!}       //这个代码是额外的,主要是为了看验证失败的时候的报错信息,laravel会将错误信息写到$errors里面去,所以能够在页面获取来看        @foreach($errors->all() as $error)            {{$error}}        @endforeach@stop

然后我们配置注册页面

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

resources/views/auth/register.blade.php@extends('layout.app')@section('content')        {!! Form::open(['url'=>'auth/register']) !!}  //注意这里是post到auth/register            {!! Form::label('name', 'Name:') !!}                {!! Form::text('name', null, ['class' => 'form-control']) !!}            {!! Form::label('email', 'Email:') !!}            {!! Form::email('email', null, ['class' => 'form-control']) !!}            {!! Form::label('password', 'Password:') !!}            {!! Form::password('password', ['class' => 'form-control']) !!}            {!! Form::label('password_confirmation', 'Password_confirmation:') !!}  //需要注意的是,这个password_confirmation是有讲究的,如果不是这样写的话,会导致validator验证不通过            {!! Form::password('password_confirmation', ['class' => 'form-control']) !!}        {!! Form::submit('注册',['class'=>'btn btn-primary form-control']) !!}        {!! Form::close() !!}        @foreach($errors->all() as $error)            {{$error}}        @endforeach@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 [        '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就是校验这个东西的,判断是否能登陆之类。

原文链接:http://www.godblessyuan.com/2016/05/26/laravel-5-2-%e7%94%a8%e6%88%b7%e6%b3%a8%e5%86%8c%e5%92%8c%e7%99%bb%e5%bd%95/

关键字:laravel, laravel5

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部