Laravel之认证服务
一.用户认证 配置文件在config/auth.php下 1.添加认证路由
// 认证路由...
Route::get('auth/login', 'Auth\AuthController@getLogin');
Route::post('auth/login', 'Auth\AuthController@postLogin');
Route::get('auth/logout', 'Auth\AuthController@getLogout');
// 注册路由...
Route::get('auth/register', 'Auth\AuthController@getRegister');
Route::post('auth/register', 'Auth\AuthController@postRegister'); 2.视图
a.登录表单
<!-- resources/views/auth/login.blade.php 下面是显示注册失败后的错误信息 -->
@if(count($errors)>0)
@foreach($errors->all() as $value)
{{$value}}
@endforeach
@endif <form method="POST" action="/auth/login">
{!! csrf_field() !!} <div>
<input type="email" name="email" value="{{ old('email') }}">
</div> <div>
Password
<input type="password" name="password" id="password">
</div> <div>
<input type="checkbox" name="remember"> Remember Me
</div> <div>
<button type="submit">Login</button>
</div>
</form> b.注册表单
<!-- resources/views/auth/register.blade.php --> <form method="POST" action="/auth/register">
{!! csrf_field() !!} <div>
Name
<input type="text" name="name" value="{{ old('name') }}">
</div> <div>
<input type="email" name="email" value="{{ old('email') }}">
</div> <div>
Password
<input type="password" name="password">
</div> <div>
Confirm Password
<input type="password" name="password_confirmation">
</div> <div>
<button type="submit">Register</button>
</div>
</form> 3.认证
a.在App/Http/Controllors/Auth的AuthController.php,按需修改以下参数 protected $redirectPath = '/dashboard';//登录成功后的重定向
protected $loginPath = '/login';//登录失败后的重定向 b.自定义字段
要修改新用户注册所必需的表单字段,或者自定义新用户字段如何存储到数据库,你可以修改AuthController类。该类负责为应用验证和创建新用户。
AuthController 的validator 方法包含了新用户的验证规则,你可以随意按需要自定义该方法。
AuthController 的create 方法负责使用Eloquent ORM 在数据库中创建新的App\User 记录。你可以基于自己的需要随意自定义该方法。 4.获取认证用户
$user = Auth::user(); 如:
class ProfileController extends Controller{
/**
* 更新用户属性.
*
* @param Request $request
* @return Response
*/
public function updateProfile(Request $request)
{
if ($request->user()) {
// $request->user() 返回认证用户实例...
}
}
} 5.判断当前用户是否有认证
if (Auth::check()) {
// The user is logged in...
} 6.使用中间件
// 使用路由闭包...
Route::get('profile', ['middleware' => 'auth', function() {
// 只有认证用户可以进入...
}]);
// 使用控制器...
Route::get('profile', [
'middleware' => 'auth',
'uses' => 'ProfileController@show'
]); 或者在控制器中
public function __construct(){
$this->middleware('auth');
} 7.登录失败次数限制
如果你正在使用 Laravel 内置的AuthController 类, Illuminate\Foundation\Auth\ThrottlesLogins trait可以用于限制用户登录失败次数。默认情况下,用户在几次登录失败后将在一分钟内不能登录,这种限制基于用户的用户名/邮箱地址+IP 地址: <?php
namespace 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{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
// AuthController 类的其它部分...
} 8.手动认证用户
使用Auth门面的attempt方法 class AuthController extends Controller{
/**
* 处理登录认证
*
* @return Response
*/
public function authenticate()
{
/*
*如果需要记住我这个功能,可以传递一个$remember参数到attempt中
*if(Auth::attempt(['email' => $email, 'password' => $password], $remember)){...}
*if (Auth::viaRemember()) {//}
*可以使用viaRemember 方法来判断用户是否使用“记住我”cookie 进行认证
*使用自动认证的记住我功能,需要生成一下key,执行php artisan key:generate
*/ if (Auth::attempt(['email' => $email, 'password' => $password])) {
// 认证通过...
return redirect()->intended('dashboard');
}
}
} attempt 方法接收键值数组对作为第一个参数,数组中的值被用于从数据表中查找用户,因此,在上面的例子中,用户将会通过email 的值获取,如果用户被找到,经哈希运算后存储在数据中的密码将会和传递过来的经哈希运算处理的密码值进行比较。如果两个经哈希运算的密码相匹配那么一个认证 session 将会为这个用户开启。 如果认证成功的话attempt 方法将会返回true 。否则,返回 false。 重定向器上的intended 方法将会将用户重定向到登录之前用户想要访问的 URL,在目标 URL 无效的情况下备用 URI 将会传递给该方法。 如果你想的话,除了用户邮件和密码之外还可以在认证查询时添加额外的条件,例如,我们可以验证被标记为有效的用户: if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// The user is active, not suspended, and exists.
} 退出:
Auth::logout();//这将清除掉session信息 9.用用户名登录,不用email登录
Laravel5.1默认使用email来验证登录的,可以在AuthController中设置$username属性来指定登录账号选项,该属性默认值是email
protected $username = 'name'; 10.其他认证方法:
Auth::login($user);//认证一个用户实例
Auth::loginUsingId(1);//通过id认证 一次性认证用户:
可以使用 once 方法只在单个请求中将用户登录到应用,而不存储任何 session 和 cookie,这在构建无状态的 API 时很有用。once 方法和 attempt 方法用法差不多:
if (Auth::once($credentials)) {
//
} 二.重置密码 1.迁移数据库
php artisan migrate 2.路由
// 密码重置链接请求路由...
Route::get('password/email', 'Auth\PasswordController@getEmail');
Route::post('password/email', 'Auth\PasswordController@postEmail');
// 密码重置路由...
Route::get('password/reset/{token}', 'Auth\PasswordController@getReset');
Route::post('password/reset', 'Auth\PasswordController@postReset'); 3.视图
重置密码,填写邮箱页面
<!-- resources/views/auth/password.blade.php -->
<form method="POST" action="/password/email">
{!! csrf_field() !!}
<div>
<input type="email" name="email" value="{{ old('email') }}">
</div>
<div>
<button type="submit">
Send Password Reset Link
</button>
</div>
</form> 点击发送邮件页面
<!-- resources/views/emails/password.blade.php -->
Click here to reset your password: {{ url('password/reset/'.$token) }} 4.密码重置表单页面
当用户点击电子邮件中的链接来重置密码时,需要提交一个密码重置表单,该视图位于resources/views/auth/reset.blade.php 。 下面是一个密码重置表单示例: <form method="POST" action="/password/reset">
{!! csrf_field() !!}
<input type="hidden" name="token" value="{{ $token }}">
<div>
<input type="email" name="email" value="{{ old('email') }}">
</div>
<div>
<input type="password" name="password">
</div>
<div>
<input type="password" name="password_confirmation">
</div>
<div>
<button type="submit">
Reset Password
</button>
</div>
</form> 5.重置密码后
如果你已经定义好路由和视图来重置用户密码,只需要在浏览器中访问这些路由即可。框架自带的PasswordController 已经包含了发送密码重置链接邮件以及更新数据库中密码的逻辑。 密码被重置后,用户将会自动登录到应用并重定向到/home 。你可以通过定义上PasswordController 的redirectTo 属性来自定义post 密码重置跳转链接: protected $redirectTo = '/dashboard'; 注意:默认情况下,密码重置令牌一小时内有效,你可以通过修改config/auth.php 文件中的选项reminder.e
xpire 来改变有效时间。 三.通过Gate检查权限 1.当前用户权限检查
用户删除某篇文章时,判断该文章是否有权限,即自己发布的,可以删除,否则不能删除 在Auth服务提供者中定义:
<?php
namespace App\Providers;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider{
/**
* 注册应用所有的认证/授权服务.
*
* @param \Illuminate\Contracts\Auth\Access\Gate $gate
* @return void
*/
public function boot(GateContract $gate)
{
parent::registerPolicies($gate);
//如果设置了该类的$policies属性,下面将无效
$gate->define('update-post', function ($user, $post) {
return $user->id === $post->user_id;
});
}
} 注意我们并没有检查给定$user 是否为 NULL,当用户未经过登录认证或者用户没有通过forUser 方法指定,Gate 会自动为所有权限返回 false。
基于类的权限 除了注册授权回调闭包之外,还可以通过传递包含权限类名和类方法的方式来注册权限方法,当需要的时候,该类会通过服务容器进行解析:
$gate->define('update-post', 'PostPolicy@update'); 使用:
class PostController extends Controller{
/**
* 更新给定文章
*
* @param int $id
* @return Response
*/
public function update($id)
{
$post = Post::findOrFail($id);
if (Gate::denies('update-post', $post)) {
abort(403);
}
}
// 更新文章...
} 当然, allows 方法和 denies 方法是相对的,如果动作被授权会返回 true ,check 方法是 allows 方法的别
名。 2.为指定的用户检查权限
为指定用户检查权限 如果你想要使用 Gate 门面判断非当前用户是否有权限,可以使用 forUser 方法:
if (Gate::forUser($user)->allows('update-post', $post)) {
//
} 也可以传递多个参数
Gate::define('delete-comment', function ($user, $post, $comment) {
//
}); 或者传入数组
if (Gate::allows('delete-comment', [$post, $comment])) {
//
} 四.通过User检查权限
1.控制器中检查
<?php
namespace App\Http\Controllers;
use App\Post;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class PostController extends Controller{
/**
* 更新给定文章
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return Response
*/
public function update(Request $request, $id)
{
$post = Post::findOrFail($id);
if ($request->user()->cannot('update-post', $post)) {
abort(403);
}
// 更新文章...
}
} 当然, can 方法和cannot 方法相反
if ($request->user()->can('update-post', $post)) {
// 更新文章...
} 2.模板中检查
Laravel 提供了 Blade 指令@can 来快速检查当前用户是否有指定权限
<a href="/post/{{ $post->id }}">View Post</a>
@can('update-post', $post)
<a href="/post/{{ $post->id }}/edit">Edit Post</a>
@endcan 可以将@can 指令和@else 指令联合起来使用
@can('update-post', $post)
<!-- The Current User Can Update The Post -->
@else
<!-- The Current User Can't Update The Post -->
@endcan 3.表单请求中检查
可以选择在表单请求的authorize 方法中使用Gate 定义的权限
/**
* 判断请求用户是否经过授权
*
* @return bool
*/
public function authorize(){
$postId = $this->route('post');
return Gate::allows('update', Post::findOrFail($postId));
} 五.策略类
由于在AuthServiceProvider 中定义所有的授权逻辑将会变得越来越臃肿笨重,尤其是在大型应用中,所以 Laravel 允许你将授权逻辑分割到多个“策略”类中,策略类是原生的 PHP 类,基于授权资源对授权逻辑进行分组。 1.生成命令
生成一个策略类
php artisan make:policy PostPolicy 生成的策略PostPolicy位于app/Policies目录下 2.映射策略类
<?php
namespace App\Providers;
use App\Post;
use App\Policies\PostPolicy;
use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider{
/**
* 应用的策略映射
*
* @var array
*/
protected $policies = [
Post::class => PostPolicy::class,
];
} 3.编写策略(PostPolicy.php)
<?php
namespace App\Policies;
use App\User;
use App\Post;
class PostPolicy{
/**
* 判断给定文章是否可以被给定用户更新
*
* @param \App\User $user
* @param \App\Post $post
* @return bool
*/
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
} 你可以继续在策略类中为授权的权限定义更多需要的方法,例如,你可以定义show , destroy , 或者addComment 方法来认证多个Post 动作。 注意:所有策略类都通过服务容器进行解析,这意味着你可以在策略类的构造函数中类型提示任何依赖,它们将会自动被注入。 4.检查策略(使用)
通过 User 模型 User 模型的 can 和 cannot 方法将会自动使用给定参数中有效的策略类。这些方法提供了
便利的方式来为应用接收到的任意User 实例进行授权 1.控制器中Gate
public function update($id)
{
$post = Post::findOrFail($id);
if (Gate::denies('update', $post)) {
abort(403);
}
// 更新文章...
} 2.通过 User 模型 User 模型的 can 和 cannot 方法将会自动使用给定参数中有效的策略类。这些方法提供了
便利的方式来为应用接收到的任意User 实例进行授权
if ($user->can('update', $post)) {
//
} if ($user->cannot('update', $post)) {
//
} 模板中
@can('update', $post)
<!-- The Current User Can Update The Post -->
@endcan 3.通过帮助函数
if (policy($post)->update($user, $post)) {
//
} 六.控制器授权 1.手动判断
默认情况下,Laravel自带的控制器基类App\Http\Controllers\Controller使用了AuthorizesRequeststrait,该trait提供了可用于快速授权给定动作的authorize方法,如果授权不通过,则抛出HttpException异常。 该authorize方法和其他多种授权方法使用方法一致,例如Gate::allows和$user->can()。因此,我们可以这样使用authorize方法快速授权更新Post的请求: <?php namespace App\Http\Controllers; use App\Post;
use App\Http\Controllers\Controller; class PostController extends Controller{
/**
* 更新给定文章
*
* @param int $id
* @return Response
*/
public function update($id)
{
$post = Post::findOrFail($id); $this->authorize('update', $post); // 更新文章...
}
} 如果授权成功,控制器继续正常执行;然而,如果authorize方法判断该动作授权失败,将会抛出HttpException 异常并生成带403 Not Authorized状态码的HTTP响应。正如你所看到的,authorize方法是一个授权动作、抛出异常的便捷方法。 AuthorizesRequeststrait还提供了authorizeForUser方法用于授权非当前用户:
$this->authorizeForUser($user, 'update', $post); 2.自动判断
通常,一个策略类方法对应一个控制器上的方法,例如,在上面的update方法中,控制器方法和策略类方法共享同一个方法名:update。 正是因为这个原因,Laravel允许你简单传递实例参数到authorize方法,被授权的权限将会自动基于调用的方法名进行判断。在本例中,由于authorize在控制器的update方法中被调用,那么对应的,PostPolicy上update方法将会被调用: /**
* 更新给定文章
*
* @param int $id
* @return Response
*/
public function update($id){
$post = Post::findOrFail($id); $this->authorize($post); // 更新文章...
}
Laravel之认证服务的更多相关文章
- [PHP] 浅谈 Laravel Authentication 的 guards 与 providers
从文档的简单介绍上来讲,有一些抽象. 个人感觉,对于概念上的大多数不理解主要还是来自于 文档不是讲设计思路,而是实际操作. 查看英文文档,通常来说可以给你最准确的直觉,而本地翻译一般比较字面或者带有理 ...
- laravel 的用户认证
1.简介 Laravel 中实现用户认证非常简单.实际上,几乎所有东西都已经为你配置好了.配置文件位于config/auth.php,其中包含了用于调整认证服务行为的.文档友好的选项配置. 在底层代码 ...
- laravel 5.3 多用户认证
不知道对不对,乱来一下!!!! 1)laravel自带了一个用户认证系统,要使用的话,直接运行一下命令就可以用了 php artisan make:auth 会生成相应的控制器.路由和模版文件 2)数 ...
- 怎么理解Laravel的核心架构
使用过larave框架的朋友都知道laravel框架里面除了提供一些基本的功能(如控制器.视图.模型)之外,还有中间件.门面.契约等,这些东西是如何在laravel框架运用起来的呢?今天就和大家详聊一 ...
- Laravel 验证 教程
英文源文章: https://www.techiediaries.com/laravel-authentication-tutorial/ 在上一篇教程中,我们已经接触过Laravel,同时介绍了最新 ...
- 【PHP】用了这么久的Laravel框架,你分析过核心架构了没
Laravel最初的设计是为了面向MVC架构的,它可以满足如事件处理.用户身份验证等各种需求.另外它还有一个由管理数据库强力支持,用于管理模块化和可扩展性代码的软件包管理器. Laravel以其简洁. ...
- TODO:Laravel增加验证码
TODO:Laravel增加验证码1. 先聊聊验证码是什么,有什么作用?验证码(CAPTCHA)是"Completely Automated Public Turing test to te ...
- TODO:Laravel 内置简单登录
TODO:Laravel 内置简单登录 1. 激活Laravel的Auth系统Laravel 利用 PHP 的新特性 trait 内置了非常完善好用的简单用户登录注册功能,适合一些不需要复杂用户权限管 ...
- TODO:Laravel 使用blade标签布局页面
TODO:Laravel 使用blade标签布局页面 本文主要介绍Laravel的标签使用,统一布局页面.主要用到到标签有@yield,@ stack,@extends,@section,@stop, ...
随机推荐
- 转 DNS原理及其解析过程【精彩剖析】
DNS原理及其解析过程[精彩剖析] http://369369.blog.51cto.com/319630/812889/ DNS原理及其解析过程 精彩剖析 网络通讯大部分是基于T ...
- 获得NOTEPAD++ Download Manager的所有下载列表的内容的au3脚本
;~ 获得NOTEPAD++ Download Manager的所有下载列表的内容的au3脚本 ;~ 作者: 鹏程万里 ;~ Email:aprial@163.com ;~ 创建日期: 2014年11 ...
- xen save/restore 过程
以下分析基于 xen4.2.3, 虚拟机都是hvm模式 使用libxl库有两种方式启动一个虚拟机,一种是 xl create xx.conf , 这种方式从一个配置文件开始启动一个虚拟机,速度相对较慢 ...
- create a large size empty file to measure transfer speed
OS : Windows open cmd fsutil file createnew file_name 1073741824 // 1GB fsutil file createnew file_n ...
- C++ 播放音频流(PCM裸流)--改善
直接上代码,如果有需要可以直接建一个win32控制台程序然后将代码拷过去改个文件名就可以用了(注意将声道和频率与你自己的文件对应).当然我自己也用VS2008写了个例子上传了,如果有需要下载地址如下: ...
- Appium+python自动化5-Appium Inspector【转载】
前言 appium Inspector从入门到放弃!反正你都打开了,那就看下为什么要放弃吧! Appium Inspector是appium自带的一个元素定位工具,上一篇介绍了如何使用uiaut ...
- Fiddler抓包10-会话框添加查看get与post请求类型【转载】
本篇转自博客:上海-悠悠 原文地址:http://www.cnblogs.com/yoyoketang/tag/fiddler/ 前言 在使用fiddler抓包的时候,查看请求类型get和post每次 ...
- mysql 主从手动切换
将主从(3307主--3308从)切换 前提:3307正常 一.将3307设为只读.命令行操作 # 修改配置文件 vim /etc/mysql/mysql-//my.cnf # 在[mysqld]中增 ...
- hdu 1598(最小生成树)
find the most comfortable road Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K ...
- MVC中Model和model的区别和用户
MVC中Model和model的区别,它们应该怎么用呢? 使用@model关键字可以定义一个Action里所对应的一个模型(经常可以叫他实体类). MVC的第一个字母M是Model,承载着View层和 ...