-
Notifications
You must be signed in to change notification settings - Fork 5
authentication
When you've built a new project using the Build command, authentication and ACL will be pretty much setup for you. The following are some short primers helping you in the configuration of these subjects.
The Garp_Auth
object allows you to read details of the current user:
$auth = Garp_Auth::getInstance();
$auth->isLoggedIn(); // @return bool
$auth->getUserData(); // @return array
Note that getUserData()
returns the contents of the cookie. This might not reflect the most recent changes in the database.
Both controllers and views contain helpers that shortcut to Garp_Auth
:
// inside a controller
$this->_helper->auth->isLoggedIn();
// inside a view
$this->auth()->isLoggedIn()
Garp uses passwordless authentication by default (inspired by passwordless.net).
You configure passwordless auth using the following options:
auth.adapters.passwordless.class = "Passwordless"
auth.adapters.passwordless.email_body_snippet_identifier = "passwordless login token email body"
auth.adapters.passwordless.email_subject_snippet_identifier = "passwordless login token email subject"
auth.adapters.passwordless.token_expires_in = "+30 minutes"
auth.adapters.passwordless.requesttoken_redirect_route = "auth_login_token_requested"
With passwordless auth, the only piece of information you got out of the box is a user's email. This makes adding administrators slightly harder.
This is why you can predefine user info in auth.ini
:
; PREFILLED USER ACCOUNTS
auth.users.0.first_name = "Hank"
auth.users.0.last_name = "Jones"
auth.users.0.role = "developer"
auth.users.0.email = "[email protected]"
This is matched by email, and all columns that are not submitted with the new user are added to the new record.
In the above scenario: Hank Jones logs in for the first time, not having a user record. Upon submitting his email address [email protected]
his info is found in the ini file and inserted along with his email.
This also helps ensure teams of developers that all have a local database they're always added with the correct role.
To set permissions for controllers and routes, see ACL — Authentication of routes.
Garp provides various authentication adapters, such as Facebook, LinkedIn and Twitter.
For all of these you are responsible for creating apps at the respective social networks.
Garp has some standard functionality for forgot password. It consists of two parts: forgot password and reset password. Basically, in the first part the user will submit his email address in order to receive an email including a password reset link.
In the second part the user resets his password after visiting said link.
Follow theses steps to implement correctly:
- Make sure the User model includes the columns
password_reset_code_expiration_date
andpassword_reset_token
:
"password_reset_code_expiration_date": {
"required": false,
"visible": false
},
"password_reset_token": {
"required": false,
"visible": false
}
- Implement the routes
forgot_password
andreset_password
(including/garp/application/configs/routes.ini
takes care of this):
routes.reset_password.route = "/g/auth/resetpassword/*"
routes.reset_password.defaults.controller = auth
routes.reset_password.defaults.action = resetpassword
routes.reset_password.defaults.module = g
routes.forgot_password.route = "/g/auth/forgotpassword/*"
routes.forgot_password.defaults.controller = auth
routes.forgot_password.defaults.action = forgotpassword
routes.forgot_password.defaults.module = g
- Configure all this (it's included in
garp_scaffold
):
; FORGOT PASSWORD
auth.forgotpassword.route = "forgot_password"
auth.forgotpassword.module = "default"
auth.forgotpassword.view = "forgotpassword"
auth.forgotpassword.layout = "layout"
auth.forgotpassword.activation_code_expiration_date_column = "password_reset_code_expiration_date"
auth.forgotpassword.activation_token_column = "password_reset_token"
auth.forgotpassword.activation_code_expires_in = "+2 days"
; auth.forgotpassword.email_partial = "partials/email/forgot_password.phtml"
auth.forgotpassword.email_snippet_identifier = "forgot password email"
auth.forgotpassword.email_snippet_column = "text"
auth.forgotpassword.email_subject = "forgot password email subject"
auth.forgotpassword.success_message = "forgot password success message"
auth.forgotpassword.failure_message = "forgot password failure message"
; RESET PASSWORD
auth.resetpassword.module = "default"
auth.resetpassword.view = "resetpassword"
auth.resetpassword.layout = "layout"
auth.resetpassword.success_message = "reset password success message"
This ties it all together. All strings are passed thru __()
so you can provide translations for 'em.
The email_partial
configuration is used if configured, otherwise a snippet will be used as the email message. In general you probably want to use the snippet because this enabled admins to edit the message.
- Last but not least: create the required views. There's not much to them, basically a form that posts to the
AuthController
. Something like this:
<!-- forgotpassword.phtml -->
<?php if ($this->successMessage): ?>
<p><?php echo $this->escape($this->successMessage) ?></p>
<?php else: ?>
<form method="post" action="<?php echo $this->url(array(), 'forgot_password') ?>">
<label for="email-field">Email</label>
<input type="email" name="email" id="email-field" required value="<?php echo $this->escape($this->email) ?>">
<?php if ($this->formError): ?>
<p class="error"><?php echo $this->escape($this->formError) ?></p>
<?php endif ?>
<button type="submit">Submit</button>
</form>
<?php endif; ?>
<!-- resetpassword.phtml -->
<?php if ($this->successMessage): ?>
<p><?php echo $this->escape($this->successMessage) ?></p>
<?php elseif ($this->error): ?>
<p class="error"><?php echo $this->escape($this->error) ?></p>
<?php else: ?>
<form method="post" action="">
<label for="password-field">New password</label>
<input type="password" name="password" id="password-field" required>
<?php if ($this->formError): ?>
<p class="error"><?php echo $this->escape($this->formError) ?></p>
<?php endif ?>
<button type="submit">Submit</button>
</form>
<?php endif; ?>