Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updating authentication docs, and fixing some formatting issues.

  • Loading branch information...
commit 18cc1a97d7defb114e7b1b9f6284d20572a58d75 1 parent 7b4897a
@nateabele nateabele authored
Showing with 106 additions and 77 deletions.
  1. +39 −27 en/06_auth/simple-auth-user.wiki
  2. +67 −50 en/06_auth/simple-authentication.wiki
View
66 en/06_auth/simple-auth-user.wiki
@@ -1,29 +1,38 @@
# Creating a user in M, V, C
-First create a 'users' data source, with at least a primary key (id) and the fields
-`username` and `password` (these could of course be renamed, but that requires more
-configuration).
+First, create a database with a `users` table or collection, with at least a primary key (usually `id` or `_id`) and the fields `username` and `password` (these could of course be renamed, but that requires more configuration).
-## The model
+## The Model
+
+Create the model in `models/Users.php`:
-Create this file `app/models/User.php`
{{{
<?php
namespace app\models;
-class User extends \lithium\data\Model {
+class Users extends \lithium\data\Model {
}
-User::applyFilter('save', function($self, $params, $chain){
- $document = $params['entity'];
- if (!$document->id) {
- $document->password = lithium\util\String::hash($document->password);
+?>
+}}}
+
+Then, create a model filter in a bootstrap file that will automatically hash user passwords before the accounts are created. The `Password` class will automatically use the most secure hashing method available on your system:
+
+{{{
+<?php
+
+use app\models\Users;

should be User i think ?

@Ciaro
Ciaro added a note

Models are plural now.

@nateabele Owner

The convention on models was changed several releases ago. They are plural now, because it makes more idiomatic sense, i.e. Users::first(), Users::all() and Users::create(), makes much more sense than User::first() and User::all(), etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+use lithium\security\Password;
+
+Users::applyFilter('save', function($self, $params, $chain) {
+ if ($params['data']) {
+ $params['entity']->set($params['data']);
+ $params['data'] = array();
}
- if (!empty($params['data'])) {
- $document->set($params['data']);
+ if (!$params['entity']->exists()) {
+ $params['entity']->password = Password::hash($params['entity']->password);

after change method to Password::hash
and have configure

//auth.php
Auth::config(array(
    'default' => array(
        'adapter' => 'Form',
        'model' => 'User',
        'fields' => array('login', 'password')
    )
));

i create user with the same passwords
1. ab2/ab2 Thu Jul 7 14:30:24 INSERT INTO "users" ("password", "login", "name", "surname", "email") VALUES ('$2a$10$2x8zKAES0TZufO31EAXaSupGcbFPaH0bmKET6DaoOxZiXRHPkwNY6', 'ab2', '', '', '');
2. ab3/ab2 Thu Jul 7 14:30:39 INSERT INTO "users" ("password", "login", "name", "surname", "email") VALUES ('$2a$10$38leGDmlzRjShPRenUXy2umfMpTp62FxczST3QmsrY/1IG56CQFDm', 'ab3', '', '', '');

as u see password is the same but hash is different and i cant log in to app by ab2/ab2 and ab3/ab2 when i change hash method to String::hash everything is ok !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
}
- $params['entity'] = $document;
return $chain->next($self, $params, $chain);
});
@@ -32,7 +41,7 @@ User::applyFilter('save', function($self, $params, $chain){
## The Controller
-Create this file : `app/controllers/UsersController`
+Create this file in `controllers/UsersController`:
{{{
<?php
@@ -64,24 +73,27 @@ class UsersController extends \lithium\action\Controller {
## The views
-Create these files:
+Then create the templates.
-`app/views/users/add.html.php`
+`views/users/add.html.php`:
{{{
-<h2>Add user</h2>
-<?=$this->form->create($user); ?>
-<?=$this->form->field('username'); ?>
-<?=$this->form->field('password', array('type' => 'password')); ?>
-<?=$this->form->submit('Create me'); ?>
-<?=$this->form->end(); ?>
+ <h2>Add user</h2>
+ <?=$this->form->create($user); ?>
+ <?=$this->form->field('username'); ?>
+ <?=$this->form->field('password', array('type' => 'password')); ?>
+ <?=$this->form->submit('Create me'); ?>
+ <?=$this->form->end(); ?>
}}}
-`app/views/users/index.html.php`
+`views/users/index.html.php`:
{{{
-<h2>Users</h2>
-<?php foreach ($users as $user) { ?>
- <?=$user->username; ?><br />
-<?php } ?>
+ <h2>Users</h2>
+
+ <ul>
+ <?php foreach ($users as $user) { ?>
+ <li><?=$user->username; ?></li>
+ <?php } ?>
+ </ul>
}}}
View
117 en/06_auth/simple-authentication.wiki
@@ -1,10 +1,10 @@
# Simple Authentication in Lithium
-If you're doing much more than simple static content delivery, chances are you'll end up needing to protect access to certain resources and functionality your application provides. Lithium's Auth setup is simple and allows you to quickly create a framework for managing and protecting those features.
+If you're doing much more than simple static content delivery, chances are you'll end up needing to protect access to certain resources and functionality your application provides. Lithium's authentication setup is simple and allows you to quickly create a framework for managing and protecting those resources.
## Data Setup
-The Auth setup makes access decisions based on information in your data store. The first thing you'll need to do is set up a model that handles user credentials. That model first needs a connection: set that up first in `app/config/connections.php`. If you're using MySQL as your data source, it should look something like this:
+The default auth setup makes decisions based on information in your data store. The first thing you'll need to do is set up a model that handles user credentials. That model first needs a connection: set that up first in `config/bootstrap/connections.php`. If you're using MySQL as your data source, it should look something like this:
{{{
use lithium\data\Connections;
@@ -23,18 +23,16 @@ If you're running with Mongo, it'll look a bit different:
{{{
Connections::add('default', array(
'type' => 'MongoDb',
- 'database' => 'li3',
- 'user' => 'myusername',
- 'password' => 'mypassword'
+ 'database' => 'mydatabase',
));
}}}
-Developers using MySQL will need a `users` table with at least the columns `id`, `username`, and `password`. Those using Mongo will need a collection in the database with a similar structure. You can customize the model and fields Auth will use as we'll see later. Make sure to take a moment and set up your `User` model as well in `app/models/User.php`:
+Developers using MySQL will need a `users` table with at least the columns `id`, `username`, and `password`. Those using Mongo will need a collection in the database with a similar structure. You can customize the model and fields that `Auth` will use as we'll see later. Make sure to take a moment and set up your `Users` model as well in `models/Users.php`:
{{{
namespace app\models;
-class User extends \lithium\data\Model {
+class Users extends \lithium\data\Model {
}
}}}
@@ -42,37 +40,23 @@ Once you've got that setup, your application more or less interacts with the dat
## User Creation
-Creating users that are compatible with the `Auth` setup is worth noting. While configurable, the default setup assumes a users data source with a sha1 hashed password field, and a username field. Please keep these defaults in mind as you create controller logic or view forms that interact with user data.
+Creating users that are compatible with the `Auth` setup is worth noting. While configurable, the default setup assumes a users data source with a hashed `password` field, and a `username` field. Please keep these defaults in mind as you create controller logic or view forms that interact with user data.
-For convenience, we also recommend setting up a filter to automatically hash user passwords when new users are created:
-
-{{{
-User::applyFilter('save', function($self, $params, $chain){
- $record = $params['entity'];
- if (!$record->id) {
- $record->password = lithium\util\String::hash($record->password);
- }
- if (!empty($params['data'])) {
- $record->set($params['data']);
- }
- $params['entity'] = $record;
- return $chain->next($self, $params, $chain);
-});
-}}}
+For convenience, we also recommend setting up a filter to automatically hash user passwords when new users are created. You can see an example filter in the __Model__ section of the [MVC auth setup instructions](simple-auth-user.wiki). You can continue to follow those instructions to create a controller and template that will allow you to generate users within your application.
## Bootstrapping Auth
-Once the data end of things is in place, Lithium needs to know you intend to use Auth, and with which settings. As with most things, this is done in a specific bootstrap file.
+Once the data handling is in place, Lithium needs to know you intend to use authentication, and with which settings. As with most things, this is done in a specific bootstrap file.
-First, point Lithium's main bootstrap file to our Auth bootstrap file. Start by editing `app/config/bootstrap.php` to include (or uncomment) a line requiring the auth bootstrap file:
+Lithium's default application template ships with a file called `config/bootstrap/session.php`, which contains default session storage settings, as well as a commented-out default authentication configuration. To enable this configuration, first edit `config/bootstrap.php` to include (or uncomment) the line requiring the session bootstrap file:
{{{
-require __DIR__ . '/bootstrap/auth.php';
+require __DIR__ . '/bootstrap/session.php';
}}}
-Next, create a new file at `app/config/bootstrap/auth.php` (if it doesn't already exist). In this auth-specific bootstrap file, we'll need to do a few things. First, make sure the Session setup is using the PHP adapter, then making some initial Auth configurations:
+Next, make sure your `Session` setup is using the PHP adapter, then create or uncomment the initial `Auth` configuration:
{{{
use lithium\storage\Session;
@@ -83,42 +67,43 @@ Session::config(array(
));
Auth::config(array(
- 'customer' => array(
- 'adapter' => 'Form',
- 'model' => 'User',
- 'fields' => array('username', 'password')
- )
+ 'default' => array('adapter' => 'Form')
));
}}}
-The Session setup is pretty straightforward, and the Auth configuration tells Lithium which adapter we want to use (one suited for credentials submitted via web form), and details about the model involved and used to match incoming credentials against.
+The `Session` setup is pretty straightforward, and the `Auth` configuration tells Lithium which adapter we want to use (one suited for credentials submitted via web form), and details about the model involved and used to match incoming credentials against.
+
+Note that the configuration information is housed in an array keyed `'default'`. `Auth` supports many different simultaneous configurations. Here we're only creating one, but you can add more (each using different adapters/configurations) as needed.
-Note that the configuration information is housed in an array keyed 'customer'. Auth supports many different simultaneous configurations. Here we're only creating one, but you could add more here as needed.
+If you're editing the bootstrap files that ship with each new application, you'll notice that the configuration presented above is quite a bit simpler than the configuration provided. This is because the manual assumes you are following the default conventions, whereas the bootstrap files make it more explicit as to what configuration options are available.
## Authentication and Controller Actions
-The first action you'll need to setup is the one that authenticates your users and adjusts the session to mark the user as identified. You could place this as you please, but it's generally accepted to see it in `Users::login()`. The suggested approach is very simple:
+The first action you'll need to setup is the one that authenticates your users and adjusts the session to mark the user as identified. You could place this as you please, but it's generally accepted to create it in `SessionsController::add()`. The suggested approach is very simple:
{{{
namespace app\controllers;
use lithium\security\Auth;
-class UsersController extends \lithium\action\Controller {
+class SessionsController extends \lithium\action\Controller {
- public function login() {
- if (Auth::check('customer', $this->request)) {
+ public function add() {
+ if ($this->request->data && Auth::check('default', $this->request)) {
return $this->redirect('/');
}
+ // Handle failed authentication attempts
}
+
+ /* ... */
}
}}}
-The meat is a conditional that calls `Auth::check()` and hands it the name of our desired Auth configuration name (remember we named the whole config array 'customer'?), and information about the current request.
+The meat is the part of the conditional that calls `Auth::check()` and hands it the name of our desired `Auth` configuration name (remember we named the whole config array `'default'`?), and information about the current request.
If the user has been successfully verified, the session is updated to mark the user as authenticated and the user is redirected to the root of the application. If there are problems with the authentication process the login view is rendered again.
-As a reference, the web form that sends the credentials and is the content of the `login` view at `app/views/users/login.html.php` should contain something that looks like this:
+As a reference, the web form that sends the credentials and is the content of the `add` view at `views/sessions/add.html.php` should contain something that looks like this:
{{{
<?=$this->form->create(null); ?>
@@ -128,28 +113,60 @@ As a reference, the web form that sends the credentials and is the content of th
<?=$this->form->end(); ?>
}}}
-The setup for protecting resources is the same as it is for initially authenticating the user (though you'd want to redirect the user to the login action on error). Use `Auth::check()` in your controller actions to make sure that sections in your application are blocked from non-authenticated users.
-
-## Checking Out
+## Protecting Resources
-Finally, you'll want to create an action that clears an end-user's authentication session on your system. Do that by making a call to `Auth::clear()` in a controller action.
+The setup for protecting resources is almost the same as it is for initially authenticating the user (though you'd want to redirect the user to the login action on error). Use `Auth::check()` in your controller actions to make sure that sections in your application are blocked from non-authenticated users. For example:
{{{
namespace app\controllers;
use lithium\security\Auth;
-class UsersController extends \lithium\action\Controller {
+class PostsController extends \lithium\action\Controller {
- public function login() {
- if (Auth::check('customer', $this->request)) {
- return $this->redirect('/');
+ public function add() {
+ if (!Auth::check('default')) {
+ return $this->redirect('Sessions::add');
}
+
+ /* ... */
}
+}
+}}}
+
+## Checking Out
+
+Next, you'll want to create an action that clears an end-user's authentication session on your system. Do that by making a call to `Auth::clear()` in a controller action.
+
+{{{
+namespace app\controllers;
+
+use lithium\security\Auth;
+
+class SessionsController extends \lithium\action\Controller {
+
+ /* ... */
- public function logout() {
- Auth::clear('customer');
+ public function delete() {
+ Auth::clear('default');
return $this->redirect('/');
}
}
}}}
+
+## Routing
+
+Finally, in order to give users slightly friendlier URLs than `/sessions/add` and `/sessions/delete`, you can wire up some very simple custom routes in `config/routes.php`. Since these are very specific routes, you'll want to add them at or near the top of your routes file:
+
+{{{
+Router::connect('/login', 'Sessions::add');
+Router::connect('/logout', 'Sessions::delete');
+}}}
+
+## More Information
+
+If you'd like to get under the hood and see how Lithium handles password hashing, auth queries & session writes, etc., check out the API documentation for the following:
+
+ - [The `Auth` class](http://lithify.me/docs/lithium/security/Auth)
+ - [The `Form` auth adapter](http://lithify.me/docs/lithium/security/auth/adapter/Form)
+ - [The `Password` class](http://lithify.me/docs/lithium/security/Password)
Please sign in to comment.
Something went wrong with that request. Please try again.