摘要:返回表示用戶的對象。相反,存儲使用單向加密算法生成的哈希。例刪除當前會話要從當前身份驗證會話中刪除所有數(shù)據(jù)包括當前存儲的經(jīng)過身份驗證的用戶,請使用靜態(tài)方法用戶操作有兩種操作可用于對經(jīng)過身份驗證的用戶執(zhí)行角色驗證和權限驗證。檢查密碼重置請求。
Luthier CI 認證框架 ( Authentication Framework ) 內(nèi)容 Contents
介紹 Introduction
創(chuàng)建用戶提供商 Creation of User Providers
用戶實例 User instance
用戶加載 Users load
密碼哈希及其驗證 Password hash and its verification
驗證用戶是否處于活動狀態(tài)并已驗證 Validate that a user is active and verified
與用戶提供商合作 Working with User Providers
用戶登錄 User login
高級用戶登錄 Advanced user login
會話 Sessions
在會話中存儲用戶 Storing a user in the session
從會話中檢索用戶 Retrieving a user from the session
自定義會話數(shù)據(jù) Custom session data
刪除當前會話 Deleting the current session
用戶操作 User Operations
角色驗證 Roles verification
權限驗證 Permissions verification
基于控制器的認證 Controller-based authentication
一般配置 General configuration
身份驗證控制器 The authentication controller
登錄表單 The login form
登出 Log out
認證事件 Authentication events
介紹 IntroductionLuthier CI Authentication Framework 是哪個用戶認證系統(tǒng)是建立在笨的結(jié)構(gòu)。它提供了兩個主要困境的答案:從中獲取用戶以及在應用程序中如何使用這些困境。
在此過程中使用用戶提供程序。用戶提供程序是一個類,負責從某個地方獲取經(jīng)過身份驗證的用戶,作為CodeIgniter之間的中介,例如,數(shù)據(jù)庫,API或甚至加載到內(nèi)存中的用戶數(shù)組。
本文針對高級用戶并具有非常特定的身份驗證需求。如果您正在尋找預先配置且易于使用的解決方案,請參閱SimpleAuth的文檔,事實上,這是您將在下面閱讀的所有內(nèi)容的實現(xiàn)。
創(chuàng)建用戶提供商 Creation of User Providers所有用戶提供商都存儲在該application/security/providers文件夾中。此外,您的類必須實現(xiàn)LuthierAuthUserProviderInterface接口,該接口定義以下方法:
public function getUserClass(); public function loadUserByUsername($username, $password = null); public function hashPassword($password); public function verifyPassword($password, $hash); public function checkUserIsActive(UserInterface $user); public function checkUserIsVerified(UserInterface $user);
讓我們首先創(chuàng)建一個名為的文件MyUserProvider.php,它將成為我們的第一個用戶提供者:
用戶實例 User instance該用戶實例是通過認證的用戶的邏輯表示:它們包含(和返回)所有的細節(jié),角色和權限。我們必須在User Provider中實現(xiàn)的第一個方法是getUserClass()返回從現(xiàn)在開始使用的用戶實例的名稱。
我們將調(diào)用我們的用戶實例MyUser,然后:
下一步是創(chuàng)建類MyUser。用戶實例文件保存在application/security/providers文件夾中。為了讓Luthier CI使用它們,類的名稱和文件名必須與getUserClass()方法中返回的名稱相匹配。
用戶實例必須實現(xiàn)LuthierAuthUserInterface接口,該接口定義以下方法:
public function __construct($instance, $roles, $permissions); public function getEntity(); public function getUsername(); public function getRoles(); public function getPermissions();實現(xiàn)所有這些方法,我們的MyUser類看起來像這樣:
user = $entity; $this->roles = $roles; $this->permissions = $permissions; } public function getEntity() { return $this->user; } public function getUsername() { return $this->user->email; } public function getRoles() { return $this->roles; } public function getPermissions() { return $this->permissions; } }我們的文件結(jié)構(gòu)如下:
application |- security | |- providers | | - MyUserProvider.php | | - MyUser.php用戶加載 Users load必須從某個地方獲取用戶,并且要實現(xiàn)以下方法,才能實現(xiàn)loadUserByUsername()該功能。
用戶加載只有兩種可能的結(jié)果:
Successful load: 找到匹配的用戶名和密碼。User Provider返回表示用戶的對象。
Failed load: 未找到用戶。以下任何異常拋出:UserNotFoundException,InactiveUserException,UnverifiedUserException或PermissionNotFoundException。
最簡單的示例是在同一個User Provider中聲明一個數(shù)組,其中包含可用的用戶:
$users = [ [ "name" => "John Doe", "email" => "john@doe.com", "password" => "foo123", "active" => 1, "verified" => 1, ], [ "name" => "Alice Brown", "email" => "alice@brown.com", "password" => "bar456", "active" => 1, "verified" => 1, ] ];話雖如此,我們將使用以下代碼更新代碼:
"John Doe", "email" => "john@doe.com", "password" => "foo123", "active" => 1, "verified" => 1, ], [ "name" => "Alice Brown", "email" => "alice@brown.com", "password" => "bar456", "active" => 1, "verified" => 1, ] ]; $userEmails = array_column($users, "email"); $foundedIndex = array_search($username, $userEmails); if($foundedIndex === false) { throw new UserNotFoundException("Invalid user credentials!"); } $user = (object) $users[$foundedIndex]; if($user->password != $password) { throw new UserNotFoundException("Invalid user credentials!"); } $userClass = $this->getUserClass(); return new $userClass( /* User data */ $user, /* Roles */ ["user"], /* Permissions */ [] ); } }現(xiàn)在,我們的用戶提供程序能夠搜索數(shù)組并在匹配時返回用戶對象,或者如果找不到用戶則拋出UserNotFoundException異常。但是,作為一般規(guī)則,密碼通常不會(也不應該)直接存儲。
相反,存儲使用單向加密算法生成的哈希。考慮這個新用戶數(shù)組:
$users = [ [ "name" => "John Doe", "email" => "john@doe.com", "password" => "$2y$10$c1iqXvXuFKZ4hI4l.LhCvuacba1fR3OX.uPfPD29j4DkyayC6p4uu", "active" => 1, "verified" => 1, ], [ "name" => "Alice Brown", "email" => "alice@brown.com", "password" => "$2y$10$xNHf.J7fbNdph2dy26JAdeQEA70aL/SG9ojrkpR3ocf1qph0Bafay", "active" => 1, "verified" => 1, ] ];每一個的密碼仍然完全相同,不同的是現(xiàn)在存儲的是你的哈希而不是純文本的密碼,
所以比較$user-> password == $password 是不夠的。
密碼哈希及其驗證要實現(xiàn)的以下方法負責在用戶提供程序中生成和驗證密碼哈希:
hashPassword(): [string] 以純文本形式接收密碼并返回其哈希值
verifyPassword(): [bool] ]以純文本和密碼哈希方式接收密碼,驗證它們是否匹配
邏輯和實現(xiàn)由開發(fā)人員自行決定。在我們的例子中,我們將使用blowfish算法,留下如下代碼:
"John Doe", "email" => "john@doe.com", "password" => "$2y$10$c1iqXvXuFKZ4hI4l.LhCvuacba1fR3OX.uPfPD29j4DkyayC6p4uu", "active" => 1, "verified" => 1, ], [ "name" => "Alice Brown", "email" => "alice@brown.com", "password" => "$2y$10$xNHf.J7fbNdph2dy26JAdeQEA70aL/SG9ojrkpR3ocf1qph0Bafay", "active" => 1, "verified" => 1, ] ]; $userEmails = array_column($users, "email"); $foundedIndex = array_search($username, $userEmails); if($foundedIndex === false) { throw new UserNotFoundException("Invalid user credentials!"); } $user = (object) $users[$foundedIndex]; if(!$this->verifyPassword($password, $user->password)) { throw new UserNotFoundException("Invalid user credentials!"); } $userClass = $this->getUserClass(); return new $userClass( /* User data */ $user, /* Roles */ ["user"], /* Permissions */ [] ); } public function hashPassword($password) { return password_hash($password, PASSWORD_DEFAULT); } public function verifyPassword($password, $hash) { return password_verify($password, $hash); } }您可能已經(jīng)注意到$password該loadUserByUsername()方法的參數(shù)必須定義為可選參數(shù)。這是因為在每個請求開始時,Luthier CI會嘗試使用其用戶Provider重新加載最后一個經(jīng)過身份驗證的用戶,這只有在可以從會話中相對安全的數(shù)據(jù)存儲中獲取用戶時才有可能,例如ID或用戶名。
因此,我們必須稍微修改我們的代碼,以確保即使沒有提供密碼,用戶提供商仍然能夠獲得用戶:
"John Doe", "email" => "john@doe.com", "password" => "$2y$10$c1iqXvXuFKZ4hI4l.LhCvuacba1fR3OX.uPfPD29j4DkyayC6p4uu", "active" => 1, "verified" => 1, ], [ "name" => "Alice Brown", "email" => "alice@brown.com", "password" => "$2y$10$xNHf.J7fbNdph2dy26JAdeQEA70aL/SG9ojrkpR3ocf1qph0Bafay", "active" => 1, "verified" => 1, ] ]; $userEmails = array_column($users, "email"); $foundedIndex = array_search($username, $userEmails); if($foundedIndex === false) { throw new UserNotFoundException("Invalid user credentials!"); } $user = (object) $users[$foundedIndex]; if($password !== NULL) { if(!$this->verifyPassword($password, $user->password)) { throw new UserNotFoundException("Invalid user credentials!"); } } $userClass = $this->getUserClass(); return new $userClass( /* User data */ $user, /* Roles */ ["user"], /* Permissions */ [] ); } public function hashPassword($password) { return password_hash($password, PASSWORD_DEFAULT); } public function verifyPassword($password, $hash) { return password_verify($password, $hash); } }不要使用md5()或sha1()函數(shù)進行密碼哈希
這些算法非常有效,任何人(使用現(xiàn)代計算機和足夠的空閑時間)都可以嘗試通過暴力破解加密。有一節(jié)介紹了PHP文檔中的password hashes ,對于那些擔心安全性這一重要方面的人來說,毫無疑問是必讀的。
驗證用戶是否處于活動狀態(tài)并已驗證這一切仍然是執(zhí)行方法checkUserIsActive()和checkUserIsVerified(),正如它們的名字,驗證用戶是主動和他們的信息被驗證。
您可以選擇激活和驗證用戶的條件。在我們的例子中,對于要激活的用戶,其值active必須等于1,并且要驗證它的值verified必須等于1。
通過實現(xiàn)這兩種方法,我們的用戶提供程序現(xiàn)在如下所示:
"John Doe", "email" => "john@doe.com", "password" => "$2y$10$c1iqXvXuFKZ4hI4l.LhCvuacba1fR3OX.uPfPD29j4DkyayC6p4uu", "active" => 1, "verified" => 1, ], [ "name" => "Alice Brown", "email" => "alice@brown.com", "password" => "$2y$10$xNHf.J7fbNdph2dy26JAdeQEA70aL/SG9ojrkpR3ocf1qph0Bafay", "active" => 1, "verified" => 1, ] ]; $userEmails = array_column($users, "email"); $foundedIndex = array_search($username, $userEmails); if($foundedIndex === false) { throw new UserNotFoundException("Invalid user credentials!"); } $user = (object) $users[$foundedIndex]; if($password !== NULL) { if(!$this->verifyPassword($password, $user->password)) { throw new UserNotFoundException("Invalid user credentials!"); } } $userClass = $this->getUserClass(); return new $userClass( /* User data */ $user, /* Roles */ ["user"], /* Permissions */ [] ); } public function hashPassword($password) { return password_hash($password, PASSWORD_DEFAULT); } public function verifyPassword($password, $hash) { return password_verify($password, $hash); } final public function checkUserIsActive(UserInterface $user) { /* * The getEntity() method is used to return an array / object / entity with the ?????????* user data. In our case, it is an object, so we can use ?????????* the following chained syntax: */ if($user->getEntity()->active == 0) { throw new InactiveUserException(); } } final public function checkUserIsVerified(UserInterface $user) { /* * The same here: */ if($user->getEntity()->verified == 0) { throw new UnverifiedUserException(); } } }完成!您已經(jīng)創(chuàng)建了第一個用戶提供程序和附加的用戶實例。您已準備好對用戶進行身份驗證。
與用戶提供商合作在使用用戶提供程序之前,您應該做的第一件事是將其上傳到您的應用程序。為此,請使用類的靜態(tài)loadUserProvider()方法Auth。
例如,要加載以前的User Provider,語法如下:
$myUserProvider = Auth::loadUserProvider("MyUserProvider");用戶登錄要執(zhí)行登錄,請使用loadUserByUsername()User Provider 的方法,其中第一個參數(shù)是用戶名/電子郵件,第二個參數(shù)是您的密碼:
// We load a User Provider: $myUserProvider = Auth::loadUserProvider("MyUserProvider"); // Returns the user object corresponding to "john@doe.com": $john = $myUserProvider->loadUserByUsername("john@doe.com", "foo123"); // Returns the corresponding user object to "alice@brown.com": $alice = $myUserProvider->loadUserByUsername("alice@brown.com", "bar456");用戶提供程序的設計使得只能使用用戶名/電子郵件登錄:
$alice = $myUserProvider->loadUserByUsername("alice@brown.com");登錄期間的任何錯誤都會產(chǎn)生異常,應根據(jù)具體情況捕獲并處理:
// ERROR: The password of john@doe.com is incorrect! // (An exception "UserNotFoundException" will be thrown) $jhon = $myUserProvider->loadUserByUsername("john@doe.com", "wrong123"); // ERROR: The user anderson@example.com doesn"t exist! // (An exception "UserNotFoundException" will be thrown) $anderson = $myUserProvider->loadUserByUsername("anderson@example.com", "test123");高級用戶登錄該用戶提供返回用戶,但這并不意味著他們真的有權登錄。checkUserIsActive()和checkUserIsVerified()方法添加方便額外的檢查。
考慮以下用戶數(shù)組:
$users = [ [ "name" => "Alex Rodriguez", "email" => "alex@rodriguez.com", "password" => "$2y$10$2nXHy1LyNL217hfyINGKy.Ef5uhxa1FdmlMDw.nbGOkSEJtT6IJWy", "active" => 0, "verified" => 1, ], [ "name" => "Alice Brown", "email" => "alice@brown.com", "password" => "$2y$10$xNHf.J7fbNdph2dy26JAdeQEA70aL/SG9ojrkpR3ocf1qph0Bafay", "active" => 1, "verified" => 0, ], [ "name" => "Jessica Hudson", "email" => "jessica@example.com", "password" => "$2y$10$IpNrG1VG53DrborE4Tl6LevtVgVfoO9.Ef9TBVgH9I10DLRnML9gi", "active" => 1, "verified" => 1, ], ];以下登錄代碼:
use LuthierAuthExceptionUserNotFoundException; use LuthierAuthExceptionInactiveUserException; use LuthierAuthExceptionUnverifiedUserException; function advanced_login($username) { $myUserProvider = Auth::loadUserProvider("MyUserProvider"); try { $user = $myUserProvider->loadUserByUsername($username); $myUserProvider->checkUserIsActive($user); $myUserProvider->checkUserIsVerified($user); } catch(UserNotFoundException $e) { return "ERROR: User not found!"; } catch(InactiveUserException $e) { return "ERROR: Inactive user!"; } catch(UnverifiedUserException $e) { return "ERROR: Unverified user!"; } return "OK: Login success!"; } var_dump( advanced_login("alex@rodriguez.com") ); // ERROR: Inactive user! var_dump( advanced_login("alice@brown.com") ); // ERROR: Unverified user! var_dump( advanced_login("jack@grimes.com") ); // ERROR: User not found! var_dump( advanced_login("jessica@example.com") ); // OK: Login success!雖然alex@rodriguez.com并且alice@brown.com存在于用戶陣列內(nèi),但是根據(jù)用戶提供者,第一個是非活動的而第二個未被驗證,并且由于用戶jack@grimes .com不存在,唯一可以登錄的用戶是jessica@example.com。
所以,你不必定義advanced_login在應用程序中一次又一次的功能,已經(jīng)有兩個方法,做同樣的事情:Auth::attempt()和Auth::bypass(),第一個用于通過用戶名和密碼,第二通過用戶名登錄登錄只。
除了處理異常外,以下表達式與前面的代碼等效:
Auth::bypass("alex@rodriguez.com", "MyUserProvider"); Auth::bypass("alice@brown.com", "MyUserProvider"); Auth::attempt("alex@rodriguez.com", "foo123", "MyUserProvider"); Auth::attempt("alice@brown.com", "bar456", "MyUserProvider");會話 Sessions如果經(jīng)過身份驗證的用戶不能繼續(xù)瀏覽,那么能夠登錄的用途是什么?所述Auth類包括用于存儲和會話中獲得的用戶的功能。
在會話中存儲用戶 Storing a user in the session要在會話中存儲用戶,請使用靜態(tài)方法store():
$alice = $myUserProvider->loadUserByUsername("alice@brown.com"); Auth::store($alice);只要您不刪除會話或它過期,這將在導航的其余部分保存經(jīng)過身份驗證的用戶。
從會話中檢索用戶要獲取存儲在會話中的用戶,請使用靜態(tài)方法user():
$alice = Auth::user();此方法返回用戶實例的對象,或者NULL如果沒有用戶存儲。
例:
$alice = Auth::user(); // The user entity // (The returned value depends on the User Provider, although the most common is that it is an object) $alice->getEntity(); // An array with the roles that the User Provider has assigned to the user $alice->getRoles(); // An array with the permissions that the User Provider has assigned to the user $alice->getPermissions();您可以使用靜態(tài)方法檢查用戶是匿名的(或邀請的)isGuest():
if( Auth::isGuest() ) { echo "Hi Guest!"; } else { echo "Welcome " . Auth::user()->getEntity()->name . "!"; }自定義會話數(shù)據(jù) Custom session data要在一個位置獲取并存儲您自己的會話數(shù)據(jù)(與身份驗證相關),請使用靜態(tài)方法session(),其第一個參數(shù)是要存儲的值的名稱,第二個參數(shù)是指定的值。
例:
// Store a value Auth::session("my_value", "foo"); // Get a value $myValue = Auth::session("my_value"); var_dump( $myValue ); // foo // Get ALL stored values var_dump( Auth::session() ); // [ "my_value" => "foo" ]刪除當前會話 Deleting the current session要從當前身份驗證會話中刪除所有數(shù)據(jù)(包括當前存儲的經(jīng)過身份驗證的用戶),請使用靜態(tài)方法destroy:
Auth::destroy();用戶操作 Users operations有兩種操作可用于對經(jīng)過身份驗證的用戶執(zhí)行:角色驗證和權限驗證。
角色驗證 Roles verification要驗證用戶是否具有某個角色,請使用static方法isRole(),其第一個參數(shù)是要驗證的角色的名稱:
Auth::isRole("user");You can supply a different user object to the one stored in session as a second argument:
$alice = Auth::loadUserProvider("MyUserProvider")->bypass("alice@brown.com"); Auth::isRole("admin", $user);權限驗證 Permissions verification要驗證用戶是否具有特定權限,請使用static方法isGranted(),其第一個參數(shù)是要驗證的權限的名稱:
Auth::isGranted("general.read");您可以將另一個用戶對象提供給存儲在會話中的用戶對象作為第二個參數(shù):
$alice = Auth::loadUserProvider("MyUserProvider")->bypass("alice@brown.com"); Auth::isGranted("general.read", $user);基于控制器的認證 Controller-based authentication到目前為止,您已經(jīng)看到Luthier CI身份驗證框架的元素多帶帶工作。好消息是你可以讓它們一起工作!這一切都歸功于我們稱之為基于控制器的身份驗證的方法。
基于控制器的身份驗證包括兩個接口的實現(xiàn),一個在控制器中,另一個在中間件中,您可以選擇自動化用戶身份驗證過程。
一般配置 General configuration您可以創(chuàng)建(盡管不是必需的)在應用程序文件夾auth.php內(nèi)調(diào)用的config文件,以配置基于驅(qū)動程序的身份驗證的選項。SimpleAuth文檔中解釋了每個選項的含義
這是配置文件的示例:
如果該文件不存在,將使用默認配置,如上所述。
身份驗證控制器 The authentication controller身份驗證驅(qū)動程序是實現(xiàn)該LuthierAuthControllerInterface接口的任何CodeIgniter控制器,它定義了以下方法:
public function getUserProvider(); public function getMiddleware(); public function login(); public function logout(); public function signup(); public function emailVerification($token); public function passwordReset(); public function passwordResetForm($token);讓我們首先創(chuàng)建一個名為的控制器 AuthController.php, 它實現(xiàn)了所有必需的方法:
load->view("auth/login.php"); } public function logout() { return; } public function signup() { $this->load->view("auth/signup.php"); } public function emailVerification($token) { $this->load->view("auth/email_verification.php"); } public function passwordReset() { $this->load->view("auth/password_reset.php"); } public function passwordResetForm($token) { $this->load->view("auth/password_reset_form.php"); } }getUserProvider()和getMiddleware()方法返回的值對應于用戶提供程序和中間件,其中包含將在后續(xù)過程中使用的身份驗證事件。對于User Provider,它將與前面的示例相同,MyUserProvider:
public function getUserProvider() { return "MyUserProvider"; }對于具有身份驗證事件的中間件,將使用一個調(diào)用MyAuthMiddleware(尚不存在),我們將在稍后討論:
public function `getMiddleware() { return "MyAuthMiddleware"; }該login()和logout()方法定義會話的開始和結(jié)束。當用戶登錄時,Luthier CI會自動截獲并處理請求,因此在我們的控制器中,我們只需要使用登錄表單顯示一個視圖:
public function login() { $this->load->view("auth/login.php"); }注銷也將由Luthier CI處理,因此我們的logout()方法在控制器級別絕對沒有任何作用:
public function logout() { return; }其余方法的實現(xiàn)取決于您,但我們會讓您了解它們的功能應該是什么:
signup(): 具有用戶注冊表的所有邏輯的方法。在這里,您必須顯示注冊表單并對其進行處理(將用戶保存在數(shù)據(jù)庫中等)
emailVerification( string $token ): 負責驗證新注冊用戶的電子郵件。通常,您已收到一封電子郵件,其中包含帶有驗證令牌($token)的鏈接。
passwordReset(): 顯示密碼重置的表單。
passwordResetForm( string $token ): 檢查密碼重置請求。幾乎總是它是一封發(fā)送給用戶的電子郵件,其中包含一個帶有密碼重置令牌的鏈接($token)
登錄表單 The login form我們的login()方法是指一個叫做的視圖auth/login.php。讓我們創(chuàng)建它:
Log in Log in
然后,我們必須在我們的web.php文件中添加以下路徑:
Route::match(["get", "post"], "login", "AuthController@login")->name("login");
訪問url時/login,必須顯示我們創(chuàng)建的登錄表單:
您可以獲得具有在身份驗證過程中發(fā)生的錯誤的安排,并在您的視圖中使用它來通知用戶。使用該Auth::messages()方法,如下所示:
Log in Log in
"Incorrect email or password", "ERR_LOGIN_INACTIVE_USER" => "Inactive user", "ERR_LOGIN_UNVERIFIED_USER" => "Unverified user", ]; ?> $message){ ?>= $errorMessages[$message] ;?>
您的登錄表已準備就緒!
您可以隨意嘗試用戶提供商中提供的任意用戶名/密碼組合。登錄時,您將被重定向到您在選項中定義的路徑$config ["auth_login_route_redirect"],或者如果沒有這樣的路徑,則重定向到應用程序的根URL。
注銷 Log out現(xiàn)在我們將配置注銷。唯一需要的是定義將要使用的路由,默認情況下它將是您調(diào)用的路由logout:
Route::get("logout", "AuthController@logout")->name("logout");
我們的路線文件最終將類似于:
Route::match(["get", "post"], "login", "AuthController@login")->name("login"); Route::get("logout", "AuthController@logout")->name("logout");認證事件 Authentication events
你還記得getMiddleware()控制器的方法嗎?返回特殊中間件的名稱:具有身份驗證事件的中間件。
我們將創(chuàng)建一個名為MyAuthMiddleware擴展抽象類的中間件LuthierAuthMiddleware,通過實現(xiàn)所有必需的方法,它將如下所示:
每種方法都對應一個身份驗證事件,如下所述:
preLogin: 用戶訪問登錄路徑時觸發(fā)的事件,無論是否登錄。
onLoginSuccess: 在成功登錄會話之后以及隨后的重定向之前立即觸發(fā)事件。
onLoginFailed: 在會話嘗試失敗后,以及隨后的重定向之前觸發(fā)的事件。
onLoginInactiveUser: 如果InactiveUserException在用戶提供程序中引發(fā)異常,則觸發(fā)事件,對應于非活動用戶登錄錯誤。
onLoginUnverifiedUser: 如果UnverifiedUserException在User Provider內(nèi)拋出異常,則觸發(fā)事件,對應于未驗證用戶登錄時的錯誤。
onLogout: 用戶關閉會話后立即觸發(fā)事件。
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/31393.html
摘要:訪問控制列表的配置與訪問控制列表使用的類別和權限類別組的名稱和的關聯(lián)排列。 簡單的認證 SimpleAuth 內(nèi)容 Contents 介紹 Introduction 安裝 Installation 第1步:復制所需的文件 Step 1: Copy the required files 第2步:安裝數(shù)據(jù)庫 Step 2: Install the database 第3步:定義...
摘要:認證介紹包含構(gòu)建用戶身份驗證系統(tǒng)所需的所有工具。不幸的是,它缺乏易于實現(xiàn),維護和擴展的集成接口或庫。激活作為可選模塊,必須首先激活認證功能。它專為最常見的身份驗證設計通過表單和數(shù)據(jù)庫進行傳統(tǒng)登錄。 認證 Authentication 介紹 Introduction CodeIgniter包含構(gòu)建用戶身份驗證系統(tǒng)所需的所有工具。不幸的是,它缺乏易于實現(xiàn),維護和擴展的集成接口或庫。 Lut...
摘要:歡迎關于是的一個插件,增加了有趣的功能,旨在簡化大型網(wǎng)站和的構(gòu)建。它是為了盡可能地與框架集成,因此在安裝后,應用程序中已存在的所有內(nèi)容應該繼續(xù)正常工作。在大多數(shù)情況下,安裝不會超過分鐘社區(qū)和支持要報告錯誤并提出更改,請訪問上的存儲庫 歡迎 關于Luthier CI Luthier CI是CodeIgniter的一個插件,增加了有趣的功能,旨在簡化大型網(wǎng)站和API的構(gòu)建。 它是為了盡可能...
摘要:安裝內(nèi)容要求安裝獲得啟用自動加載和掛鉤將與您的應用程序連接初始化要求安裝獲得需要通過安裝。編寫權限如果在創(chuàng)建基本文件期間出現(xiàn)錯誤,則可能是由于權限不足。確保該文件夾具有寫入權限 安裝 ( Installation ) 內(nèi)容 ( Contents ) 要求 Requirements 安裝 Installation 獲得Luthier CI Get Luthier CI 啟用Co...
摘要:寫入權限確保該文件夾具有寫入權限,以便這些命令正常工作僅適用于開發(fā)出于安全原因,如果您的應用程序配置了或環(huán)境,則將禁用這些命令激活默認情況下禁用工具。 命令行 Command line 內(nèi)容 Contents 介紹 Introduction 句法 Syntax 使用CLI路由 Using CLI routes 內(nèi)置CLI工具 Built-in CLI tools 激活 Ac...
閱讀 1302·2021-10-08 10:04
閱讀 1934·2021-09-04 16:40
閱讀 2545·2019-08-30 13:21
閱讀 2289·2019-08-29 15:10
閱讀 2857·2019-08-29 12:35
閱讀 1197·2019-08-26 17:41
閱讀 3070·2019-08-26 17:03
閱讀 1147·2019-08-26 12:01