이 글은 Laravel 5.4 버전의 Auth 모듈 코드 분석 및 작성을 기반으로 합니다.
모듈 구성
Auth 모듈은 기능적으로 파일 구성 측면에서 사용자 인증과 권한 관리, IlluminateAuthPasswords 디렉토리는 비밀번호 재설치 모듈입니다. IlluminateAuth는 사용자 인증 및 권한 관리를 담당하는 모듈입니다. 로그인, 비밀번호 수정 및 비밀번호와 같은 일련의 특정 논리 구현을 제공합니다. 재설정 다음 그림은 인증 모듈의 다양한 파일 간의 관계를 보여줍니다.
사용자 인증
HTTP 자체는 일반적으로 시스템 상호 작용 과정에서 상태가 없습니다. 식별은 인증된 사용자를 결정하는 데 사용됩니다.
구성 파일 해석
return [ 'defaults' => [ 'guard' => 'web', ... ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], ], ], ];
아래에서 올라가서 이해하세요.
providers는 사용자 데이터를 제공하는 인터페이스이며 여기에 드라이버 개체와 대상 개체가 표시되어야 합니다. name users는 eloquent에 의해 구동되는 공급자 집합의 이름이고 modal은 AppUser::class입니다.
guards 구성의 일부는 인증 관리 부분에 대한 것입니다. 하나는 웹이라고 하며, 다른 하나는 API입니다. 웹 인증은 세션 상호 작용을 기반으로 하며, 사용자 ID는 sessionId에 따라 획득되며, API 인증은 토큰 값 상호 작용을 기반으로
사용됩니다. defaults 항목은 웹 인증이 기본적으로 사용됨을 나타냅니다.
세션 바인딩 인증 정보:
// $credentials数组存放认证条件,比如邮箱或者用户名、密码 // $remember 表示是否要记住,生成 `remember_token` public function attempt(array $credentials = [], $remember = false) public function login(AuthenticatableContract $user, $remember = false) public function loginUsingId($id, $remember = false)HTTP 기본 인증, 인증 정보는 요청 헤더 뒤에 있습니다.
public function basic($field = 'email', $extraConditions = [])를 통해 요청됩니다. 현재 세션에서만 인증되며 해당 세션에는 인증 정보가 기록되지 않습니다.
public function once(array $credentials = []) public function onceUsingId($id) public function onceBasic($field = 'email', $extraConditions = [])인증 과정(등록, 비밀번호 분실 포함) 중 정의된 이벤트는 다음과 같습니다. Attempting Attempt to verify event
인증 통과 이벤트 Failed 인증 실패 이벤트 Lockout 실패 횟수가 한도를 초과하여 다시 접속 요청을 잠급니다. remember_token을 통해 로그인 성공 시 호출되는 Logi 이벤트 로그아웃 사용자 종료 이벤트 등록됨 사용자 등록 이벤트다른 인증 방법도 있습니다: 인증된 사용자가 있는지 확인: Auth::check()현재 인증된 사용자 가져오기: Auth::user()시스템 종료: Auth: :logout() 비밀번호 처리구성 해석
return [ 'defaults' => [ 'passwords' => 'users', ... ], 'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 60, ], ], ]아래에서 위로 구성을 살펴보세요. passwords 배열은 비밀번호를 재설정하기 위한 구성이며 사용자는 구성 체계의 별칭이며 다음 세 가지 요소를 포함합니다. 공급자(위의 공급자 배열인 사용자 구성표 제공), 테이블(비밀번호 재설정 토큰을 저장하는 테이블), 만료(토큰 만료 시간) 기본 항목은 기본 비밀번호 재설정 구성표를 설정합니다.
비밀번호 재설정 호출 및 구현;
먼저 Laravel의 비밀번호 재설정 기능이 어떻게 구현되는지 살펴보세요:
public function reset(array $credentials, Closure $callback) { // 验证用户名、密码和 token 是否有效 $user = $this->validateReset($credentials); if (! $user instanceof CanResetPasswordContract) { return $user; } $password = $credentials['password']; // 回调函数执行修改密码,及持久化存储 $callback($user, $password); // 删除重置密码时持久化存储保存的 token $this->tokens->delete($user); return static::PASSWORD_RESET; }그런 다음 FoundationAuth 모듈에 의해 캡슐화된 비밀번호 재설정 모듈이 어떻게 호출되는지 살펴보세요:
// 暴露的重置密码 API public function reset(Request $request) { // 验证请求参数 token、email、password、password_confirmation $this->validate($request, $this->rules(), $this->validationErrorMessages()); // 调用重置密码的方法,第二个参数是回调,做一些持久化存储工作 $response = $this->broker()->reset( $this->credentials($request), function ($user, $password) { $this->resetPassword($user, $password); } ); // 封装 Response return $response == Password::PASSWORD_RESET ? $this->sendResetResponse($response) : $this->sendResetFailedResponse($request, $response); } // 获取重置密码时的请求参数 protected function credentials(Request $request) { return $request->only( 'email', 'password', 'password_confirmation', 'token' ); } // 重置密码的真实性验证后,进行的持久化工作 protected function resetPassword($user, $password) { // 修改后的密码、重新生成 remember_token $user->forceFill([ 'password' => bcrypt($password), 'remember_token' => Str::random(60), ])->save(); // session 中的用户信息也进行重新赋值 $this->guard()->login($user); }"비밀번호 찾기 => 이메일 보내기 => 비밀번호 재설정" 일반 프로세스는 다음과 같습니다. "비밀번호 찾기"를 클릭하고 라우팅 구성을 통해 "비밀번호 찾기" 페이지로 이동하면 입력할 페이지에 "전송할 이메일" 필드가 있습니다. 전송될 "은 데이터베이스입니다. 존재하는 경우 비밀번호 재설정 이메일이 해당 사서함으로 전송됩니다. 비밀번호 재설정 이메일에 링크가 있습니다(클릭하면 토큰이 비밀번호 변경 페이지로 이동합니다). "이메일", "비밀번호" 및 "비밀번호 확인"의 세 가지 필드를 입력한 후 홈페이지에서 비밀번호 재설정 API에 액세스하려면 토큰을 가져오세요. 이메일, 비밀번호 및 비밀번호 확인을 확인한 후 토큰이 유효한지 확인합니다. 그렇다면 재설정에 성공한 것입니다.
권한 관리
권한 관리는 메모리 공간에 의해 유지되는 배열 변수입니다. 구조는 다음과 같습니다.$abilities = array( '定义的动作名,比如以路由的 as 名(common.dashboard.list)' => function($user) { // 方法的参数,第一位是 $user, 当前 user, 后面的参数可以自行决定 return true; // 返回 true 意味有权限, false 意味没有权限 }, ...... );하지만 $ability만 사용하고, 코드에 정의된 부분만 사용하게 됩니다. 하나로 모으기가 너무 번거로워서 정책 전략 클래스가 나타납니다. 정책 클래스는 해당 관계를 정의합니다. 예를 들어 기사를 예로 들어 보겠습니다. 이를 위해 사용할 수 있는 Post라는 모달 엔터티 클래스가 있습니다. 엔터티 클래스는 PostPolicy 권한 클래스를 정의하고 일부 작업을 정의합니다.
class PostPolicy { // update 权限,文章作者才可以修改 public function update(User $user, Post $post) { return $user->id === $post->user_id; } }그런 다음 ServiceProvider에 등록하면 확인하려는 클래스가 Post 개체인 경우 제공한 작업 이름을 추가하면 시스템이 해당 메서드를 찾을 수 있음을 알 수 있습니다. PostPolicy 클래스의
protected $policies = [ Post::class => PostPolicy::class, ];어떻게 호출하나요? ability 배열에 정의된 권한의 경우: 현재 사용자에게 common.dashboard.list 권한이 있는지 여부: Gate::allows('common.dashboard.list')현재 사용자에게 common.dashboard.list 권한이 있는지 여부 : ! Gate::denies('common.dashboard.list')현재 사용자에게 common.dashboard.list 권한이 있는지 여부: $request->user()->can('common.dashboard.list') 현재 사용자에게 common.dashboard.list 권한이 있는지 여부:! $request->user()->cannot('common.dashboard.list')
指定用户是否具备common.dashboard.list权限:Gate::forUser($user)->allows('common.dashboard.list')
对于policy策略类调用的权限:
当前用户是否可以修改文章(Gate 调用):Gate::allows('update', $post)
当前用户是否可以修改文章(user 调用):$user->can('update', $post)
当前用户是否可以修改文章(用帮助函数):policy($post)->update($user, $post)
当前用户是否可以修改文章(Controller 类方法中调用):$this->authorize('update', $post);
当前用户是否可以修改文章(Controller 类同名方法中调用):$this->authorize($post);
指定用户是否可以修改文章(Controller 类方法中调用):$this->authorizeForUser($user, 'update', $post);
有用的技巧
获取当前系统注册的权限,包括两部分abilities和policies数组内容,代码如下:
$gate = app(\Illuminate\Contracts\Auth\Access\Gate::class); $reflection_gate = new ReflectionClass($gate); $policies = $reflection_gate->getProperty('policies'); $policies->setAccessible(true); // 获取当前注册的 policies 数组 dump($policies->getValue($gate)); $abilities = $reflection_gate->getProperty('abilities'); $abilities->setAccessible(true); // 获取当前注册的 abilities 数组 dump($abilities->getValue($gate));
推荐教程:《Laravel教程》
위 내용은 Laravel의 인증 모듈 사용법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!