My first zf presentation part two

Post on 28-Jan-2015

107 views 0 download

Tags:

description

 

Transcript of My first zf presentation part two

My Very First…Model View Controller Web Applicationwith the Zend Framework – Part Deux

New York CityZF Meetup

Previously…

• MVC Basics– Zend_Controller_Action, Zend_View, view scripts

• ZF application structure– Where do I find file xyz?

• Database– Zend_DB

• Forms– Zend_Form, Zend_Form_Element, Zend_Validate

• Zend Tool– Project set-up tasks simplified

Part One Part Two

• Finished With– User table set-up– Registration form completed

• Added between Part One and Part Two: – User home page (home action in UserController)– A few more users– Extension of Zend_Controller_Action• Explanation forthcoming

Part Two

• Security– Authentication– Authorization

• ZF Dispatch Process• Action helpers• Layouts• View Helpers (briefly)

Step 8: Security

• Need to make sure non-logged in users can’t see user home page.– Should still be able to see user register page and

about page.• Members should be able to do everything

except admin tasks

User Access Security

• General Pattern (not ZF specific) - two components– Authentication• Verify that a user is who they say they are

– Authorization • Verify that an authenticated user is allowed to do

something

User Access Security

• Analogous to getting into a bar:– The bouncer authenticates you when he looks at

your ID and decides whether it’s real or not– The bouncer authorizes you to enter when he sees

that your ID says you’re 21, and that you’re not beyond redemption for the night

ZF – User Access Security

• Authentication – Zend_Auth– Adapter based authentication, including:• Zend_Db (users stored in DB)• OpenID• LDAP• Others

• Authorization – Zend_Acl– Access Control List– Your app’s bouncer

Zend_Auth

• Zend_Auth is a class, implements singleton• Access singleton auth instance with:– Zend_Auth::getInstance()

• Instance methods for:– Is user logged in? - Zend_Auth::hasIdentity()– What is user’s identity? – Zend_Auth::getIdentity()– Clear identity – Zend_Auth::clearIdentity()– Adapter authenticate– Zend_Auth::authenticate($adapter)

Zend_Auth

• Can handle storage of identity– Defaults to storage as session variable

• Coordinates authentication, doesn’t do it– Adapters handle actual authentication– I.e., user password lookup is handled by

MyApp_Auth_Adapter

Auth: Deny Guest Access to Home

• Grab auth instance, test for identity:– If identity, user is logged in– If not, user is guest, redirect to login

• Note, no need for adapter here as we’re not performing authentication

Auth: Use of Adapters for Login

• Redirect logged in user home.• Process login attempt.

Db Adapter: Setup

• Constructor needs– Db adapter– Name of table– Name of ID column (i.e. user name, email)– Name of credential column (i.e. password)

Db Adapter: Setup

• Pass in posted email and password– setIdentity – Tell the adapter the identity the user

is trying to log in with.– setCredential – Tell the adapter the credential the

user is trying to log in with.

Db Adapter: Authenticate…

• Well, kind of• Don’t use adapter’s authentication method

directly, use Zend_Auth::authenticate and pass the adapter– Let’s Zend_Auth store identity in session

Auth: Authentication Successful?

• Zend_Auth::authenticate returns instance of Zend_Auth_Result

• Use Zend_Auth_Result::isValid to determine success or failure– Zend_Auth_Result :: getCode to get details (useful

on auth failure)

Auth Accomplished!

• We can now control access based on log in status!

• Good enough for simple access control needs:– Any user has access to home action– No guest has access to home action

Auth Accomplished?

• What about something like delete user action?– Being logged in isn’t good enough

• Would like to base decision on information about the user– Is this user an admin?– Is this user a plain vanilla user?

Auth Accomplished…But Not Authorization

• What we’re asking is: does this authenticated user have permission to do this thing?

• This isn’t the responsibility of auth• Authorization is the process of determining if

a user has access to do an action.• Generally, two steps:– Determine type of user– Ask if that type of user is allowed to perform the

requested action (delete a user, edit a task, etc)

Authorization: Zend_Acl

• ZF has Access Control List component– Effectively, table of rules for access– Rules can be specified flexibly and hierarchically

• One of ZF’s best components

Access Control Concepts

• Role – user access level (your role in a system)• Resource – a thing a user requests access to• Privilege – describes an action a user may

perform on a resource

• Roles and resources can be hierarchical– Member inherits privileges from guest– Admin inherits privileges from member

Zend_Acl

• Access control list is an object.• Four steps to configure– Create object– Add roles– Add resources– Set rules

• Query acl using Zend_Acl::isAllowed()

TaskMaster Access Control Roles

• Start with 4 roles, must be declared in advance:– Guest– Member, inherits from guest– Staff, inherits from member– Admin, inherits from Staff

TaskMaster Access Control Resources

• Strategy:– One controller = one resource– One action = one privilege

• Doesn’t have to be done this way, but is often sensible and convenient later on.

• 3 Resources, do need to be declared in advance– User– Task– Index

• Privileges don’t need to be declared in advance

ACL Creation: Roles and Resources

• Add roles and resources first– Exception thrown if an unregistered role or

resource is referred to:

ACL Configuration: Create Rules

• “Rules” tell the ACL when to allow/deny a user access to a resource– “Allow members to edit their info”– “Don’t let members delete other members”– “Allow an admin to do anything”

• Syntax: – $acl->allow/deny($user, $resource, $privilege)– Parameters are flexible, see ZF reference

ACL Configuration: Rules

• Allow the admin all privileges on all resources• Deny guest all privileges on all resources– Note that this denies all privileges for anyone who

inherits from guest as well (member, staff)– Note that deny all happens by default, this is to be

explicit

ACL Configuration: Guest Rules

• Allow guest access to:– Index controller pages (about page, etc)– Register and login insider UserController– Error controller (technicality, but good to do for

later)

ACL Configuration: Member Rules

• Allow member access to:– Do anything inside UserController, except delete a

user– Do anything with tasks• Note that further security is needed to make sure

members can’t mess with other people’s tasks, but this won’t happen here.

ACL Configuration: Staff

• Let staff delete users:

Access Control Accomplished…

• Well, Access Control created…

Point of Auth and Access Control?

• Fantastic, I have things that will control access to my app

• Where do I use them?

Point of Control?

• Could test inside each action method…

Point of Access Control?

• Works, but not ideal:– Very redundant– What if you want to add logic later• Logging• Blacklist IP of repeat offender• Etc

– Separation of concerns: action method should only have to worry about what it does.

Point of Access Control?

• What we’d like is to:– Put the Access Control logic in one place, have it

run before all action methods• If the user is allowed, proceed as usual• If not, redirect to login (for guest) or home (for

member)

• Almost like a “onPreAnyActionMethod” hook…

Detour: ZF Dispatch Process

• Stuff happens before and after action method• Hooks exist in ZF controller architecture,

various ways to plug in.• Observe an event, idea similar to– Javascript events– Doctrine model/connection events– Firefox plugins

• Let’s take a look at the app flow…

ZF Request Dispatch Process

• Simplified ZF Request Process– Request to Response

Point of Access Control in ZF Request Dispatch Process

• preDispatch lets us make a decision before the action runs

preDispatch

• preDispatch happens before the action method is dispatched

• Always runs, hard-coded into controller architecture

• Can redirect or otherwise alter request in preDispatch

• 3 ways to hook into preDispatch

ZF – preDispatch Phase

• Three parts of preDispatch

ZF – preDispatch Options

• Three ways to hook into preDispatch phase:– Use preDispatch method of the controller– Use action helpers – Use front controller plugins

preDispatch Option #1: Method of Controller

• Zend_Controller_Action has preDispatch method.

• Override in extending class.

preDispatch Option #1: Method of Controller

• Pros:– Simple– Always runs before action method

• Cons– Can be overridden in extending class• Extending class must call parent method, doesn’t

happen implicitly

– All controllers must extend same base class

preDispatch Options #2 and #3:Plugins and Action Helpers

• Plugins and Action helpers are:– Objects– With preDispatch methods– preDispatch methods are run prior to action

method– Will run no matter what controller is being

invoked

preDispatch Options #2 and #3:Plugins and Action Helpers

• Similar to:– Javascript event listeners– Doctrine event listeners

• Can plugin as many or as few as you like

preDispatch Options #2 and #3:Plugins and Action Helpers

• Pros:– Harder to accidentally over-ride: aren’t over-riden by

sub-classes of controller base class.– Run before action method of any controller– Highly modular– Hook into multiple events with one class

• Cons:– Small increase in complexity:

• Need to know what they are• Another place to look for logic

Plugins and Action Helpers

• Plugins register with Front Controller– Plugins have more opportunities to hook into dispatch

flow (7 hooks available)• Action helpers register with a special broker– Can access controller object easily in pre and post

dispatch– Can also provide extra functionality (help) to the

controller

• We’ll deal with action helpers

Action Helpers

• This is an action helper…that’s it• preDispatch method is called inside ZF

Auth Action Helper:

• Get the user object, if available, inject into controller

ACL Action Helper

• Grab user from controller (assume Auth helper goes first)

• Redirect to login if access denied (simply reset action and controller name)

Security Accomplished!

• Use Zend_Auth to verify a user is who he says he is

• Use Zend_Acl to verify that person can do what he’s requesting

• Use action helpers (or front controller plugins) to reliably hook into application flow without repeating yourself

While We’re on Action Helpers

• Register helpers with the helper broker:– Zend_Controller_Action_HelperBroker::addHelper(new

Zx_Controller_Action_Helper_Acl());• Need not implement pre/postDispatch• Access in action methods for help with complex logic– From with controller:

• $this->_helper->helperName (overloading)• $this->getHelper($helperName)

• Can help keep controller classes clean• Many built in, including…

Action Helpers: Redirector

• Lets you redirect user without dealing with headers

Action Helpers: JSON

• Easily send JSON response, appropriate headers sent, data encoded.

Action Helpers: Action Stack

• Stack actions to run after the current action.• Can help widgetize pages:– User edit page might be combination of 4 forms,

rather than 1 giant form

Not Bad…

• We have:– DB access up and running– User system running– Basic security

• And we can make and user action helpers

• But…

Doesn’t Look Great

Back to the View

• Would like to create a site wide look and feel• Each view script should only be responsible for

it’s content• Almost want a template to inject view script

output into

Site Wide Layout: Zend_Layout

• ZF has layout component– Single view script that runs after main content is

generated– Can inject content into the desired location– Can change layout script in different parts of site– Disable if necessary (JSON/XML response, etc)• Integrates with JSON action helper, other components

Zend_Layout: Setup

• Enable in application.ini– Enables layout resource, sets default layout script– /views/layouts/default.phtml will be layout• Default specified in first line, phtml ext assumed

Zend_Layout: Layout File

• View script output injected into markup

Zend_Layout: Voila!

• Modified from http://www.456bereastreet.com/lab/developing_with_web_standards/csslayout/2-col/finished.html

Layout: Explained

• View script output is buffered and stored in response object– Output stored in content “segment” by default.– Output can be organized into different segments.

• Layout view script has access to the response segments, and injects them into the template

Layout: Explained

• Q: How does the layout script get the response segments:

• A: The layout view helper.

View Helpers

• View Helpers are to View Scripts what Action Helpers are to Action Methods– Objects plugged into the view to separate complex

logic from display logic– From inside a view script, access with:• $helper = $this->helperName

– $layoutHelper = $this->layout– $urlHelper = $this->url

Layout View Helper

• Here, the layout view helper is accessed…• …and it’s content property contains the

content segment of the response

URL View Helper

• Forms URL based on a route– Useful when doing non-standard routing

Action View Helper

• Run an action, grab the output, and place it where you want it:

Further Resources

• ZF Reference Guide– http://framework.zend.com/manual/en/

• Zend Casts– http://www.zendcasts.com/

• The Internet– www.google.com

Questions?

Isaac Foster http://www.linkedin.com/in/isaaczfosterisaac.z.foster@gmail.com

New York City area Zend Framework Meetup

http://www.meetup.com/ZendFramework-NYCmetro/

Affiliated with http://www.nyphp.org/

Alan Seiden http://www.alanseiden.comalan@alanseiden.comTwitter: @alanseiden

Thanks for attending “Your First Zend Framework Project, Part Two”

presented on March 22, 2011 by

Sign up to hear about all our ZF meetups at http://www.meetup.com/ZendFramework-NYCmetro/