版本说明:Laravel 5.3
已有用户的用户表(提前先创建好,生成好数据)
Auth 认证原理简述
Laravel 的认证是使用 guard 与 provider 配合完成, guard 负责认证的业务逻辑,认证信息的服务端保存等; provider 负责提供认证信息的持久化数据提供。
请求提交给 guard, guard 从 provider 里取出数据(类似用户名、密码等),验证输入数据与服务器端存储的数据是否吻合。如果提交的数据正确,再做 session 等业务的处理(如有需要)。
认证脚手架
首先我们导入 Laravel 的自带的认证脚手架
php artisan make:auth
执行数据库迁移(看需求吧有用户表的就不用生成数据表):
php artisan migrate
修改 Auth 认证的配置文件config/auth.php
在 gurads 处,添加 admin guard 用于后台管理员认证,添加user guard用户普通用户认证
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'admins',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'user' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
在 providers 处添加 admins provider,使用 Administrator 模型
在 providers 处添加 user provider,使用 UniUser 模型
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => \App\Models\UniUser::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => \Encore\Admin\Auth\Database\Administrator::class,
],
],
生成对应的Moble
php artisan make:mode UniUser
php artisan make:mode Administrator
修改模型例如:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
class UniUser extends Model implements AuthenticatableContract
{
use Authenticatable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'MemName', 'PassWord','NickName','RegTime','IP','LastIP','LastTime',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'PassWord',
];
public function getAuthPassword()
{
return $this->attributes['PassWord'];
}
//
protected $table = "uni_user";
protected $primaryKey = "ID";
public $timestamps =false;
}
创建用户界面
创建用户页面(0_0)懒的创建了因为,脚手架已经创建了登录、注册、找回的Controller了
修改 web.php的路由,注意middleware
是和Auth.php中配置的对应
Route::get('/', 'SxolIndexController@index');
Route::group(['prefix' => 'user'], function () {
Route::group(['middleware' => 'auth.user'], function () {
Route::get('/', 'User\UserIndexController@index');
});
Route::get('login', 'User\LoginController@showLoginForm')->name('user.login');
Route::post('login', 'User\LoginController@login');
Route::post('logout', 'User\LoginController@logout');
Route::get('register','User\RegisterController@showRegistrationForm')->name('user.register');
Route::post('register','User\RegisterController@register');
});
编辑LoginController.php
namespace App\Http\Controllers\User;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $maxLoginAttempts = 5; //每分钟最大尝试登录次数
protected $lockoutTime = 600; //登录锁定时间
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/user/';
/**
* 显示后台登录模板
*/
public function showLoginForm()
{
return view('user.login');
}
/**
* 使用 user guard
*/
protected function guard()
{
return auth()->guard('user');
}
protected function username()
{
return 'memname';
}
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest.user', ['except' => 'logout']);
}
/**
* @param Request $request
*/
protected function validateLogin(Request $request)
{
$this->validate($request,[
'memname' => 'required',
'password' => 'required',
], [
'memname.required' => '用户名必须',
'password.required' => '密码必须'
]);
}
/**
* 重写登录
* @param Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response
*/
public function login(Request $request)
{
$this->validateLogin($request);
$throttles = $this->isUsingThrottlesLoginsTrait();
$lockedOut = $this->hasTooManyLoginAttempts($request);
if ($throttles && $lockedOut) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
if ($this->guard()->attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
if ($throttles && ! $lockedOut) {
$this->incrementLoginAttempts($request);
}
return $this->sendFailedLoginResponse($request);
}
protected function handleUserWasAuthenticated(Request $request, $throttles)
{
if ($throttles) {
$this->clearLoginAttempts($request);
}
// My Event Here
return redirect()->intended($this->redirectPath());
}
protected function getCredentials(Request $request)
{
return $request->only('memname', 'password');
}
/**
* Determine if the class is using the ThrottlesLogins trait.
*
* @return bool
*/
protected function isUsingThrottlesLoginsTrait()
{
return in_array(
ThrottlesLogins::class, class_uses_recursive(static::class)
);
}
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->forget($this->guard()->getName());
$request->session()->regenerate();
return redirect('/user');
}
}
编辑 login.blade.php
@extends('layouts.user')
@section('content')
<div class="container">
<div class="row" >
<div id="logindev" class=" col-md-3 panel panel-default ">
<div class="panel-heading">登录</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ url('/user/login') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('memname') ? ' has-error' : '' }}">
<div class="col-md-12">
<div class="input-group">
<span class="input-group-addon" id="memname-addon">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
</span>
<input id="memname" type="text" class="form-control" placeholder="用户名/手机号"
name="memname" value="{{ old('memname') }}"
aria
dby="memname-addon" required autofocus>
</div>
@if ($errors->has('memname'))
<span class="help-block">
<strong>{{ $errors->first('memname') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<div class="col-md-12">
<div class="input-group">
<span class="input-group-addon" id="password-addon">
<span class="glyphicon glyphicon-lock" aria-hidden="true"></span>
</span>
<input id="password" type="password" class="form-control" placeholder="请输入密码"
name="password" aria-describedby="password-addon" required>
</div>
@if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<button type="submit" class="btn btn-primary col-xs-12">
登录
</button>
</div>
</div>
<div class="form-group">
<div class="col-md-12">
<div class="checkbox col-xs-6" style="padding-left: 0px">
<label>
<input type="checkbox"
name="remember" {{ old('remember') ? 'checked' : ''}}> 下次自动登录
</label>
</div>
<a class="btn btn-link col-xs-6" style="text-align: right;padding-right: 0px"
href="{{ url('/password/reset') }}">
忘记密码
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<link href="/css/user.css" rel="stylesheet">
@endsection
后台管理认证中间件
php artisan make:middleware AuthUser
编辑 AuthUser
<?php
namespace App\Http\Middleware;
use Closure;
class AuthUser
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (auth()->guard('user')->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('user/login');
}
}
return $next($request);
}
}
创建登录跳转中间件,用于有些操作在登录之后的跳转
php artisan make:middleware GuestUser
编辑GuestUser
<?php
namespace App\Http\Middleware;
use Closure;
class GuestUser
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (auth()->guard('user')->check()) {
return redirect('/user');
}
return $next($request);
}
}
在 app/Http/Kernel.php
中注册以上中间件
'auth.user' => \App\Http\Middleware\AuthUser::class,
'guest.user' => \App\Http\Middleware\GuestUser::class,