Skip to content

authentication

Harmen Janssen edited this page Jul 5, 2016 · 13 revisions

Authentication basics

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.

Reading current user data

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()

Passwordless auth

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"

Predefining user records

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.

Setting access rights

To set permissions for controllers and routes, see ACL — Authentication of routes.

How to allow 3rd party login?

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.

Forgot password

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 and password_reset_token:
"password_reset_code_expiration_date": {
	"required": false,
	"visible": false
},
"password_reset_token": {
	"required": false,
	"visible": false
}
  • Implement the routes forgot_password and reset_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; ?>
Clone this wiki locally