CQ/AEM Best Practices
Structure & Components:
- Make sure what you are building does not already exist: CQ is huge. There are 307 OSGi bundles and approximately 34 foundational components, 2 custom taglibs comprising 13 tags, a dozen or so standard JSP actions, with as many JSP Core tags and many other CQ components specific to add-ons. The chance the core of what you are building already exists in one form or another is very good. Spend 15 or 30 minutes doing research before you build. Eventually the research time will be nominal due to your ever increasing awareness of what CQ has to offer, as well as what is available in your own application.
- Design, build templates and components for extension: Always design and break up your JSPs logic (if huge) N sections, each with its own JSP. Also, each section should have a "switch" in the component dialog to "disable" it from view. This organization of the component should be one that keeps extension in mind. Each section should be easily customizable by providing a new JSP for it in the extended component, while still relying upon "core" component functionality.
- Reuse & Overlay: When creating your own components or customizing an existing component it is often easiest (and safest) to re-use existing definitions. The same principle also applies to other elements within CQ, for example the error handler. This can be done by copying and overlaying the existing definition. In other words, copying the definition from “/libs” to “/apps/<your-project>”. This new definition, in /apps, can be updated according to your requirements.
- Make sure to protect your website against XSS: Make use of the CQ OOTB XSSApi in your code. CQ applies the principle of filtering all user-supplied content upon output. Preventing XSS should be given the highest priority during both development and testing.
For example: Instead of <head><title><%= title %>< /title></head>
Use <head><title><%= xssAPI.encodeForHTML (title); %>< /title></head>
- Allow all input - Encode all output: Do not filter or encode input that gets stored but always protect the user on output.
- Encode at the very end: Encode the output-statement itself not intermediate values, so it is always obvious that an output statement is not dangerous, and you know you are encoding for the right context.
- Don’t think too much: Encode the content no matter where it is coming from. Your code might be copied or included, and the ACLs on the property might change.
- Never do it yourself: Never write the encoding/filtering methods yourself. XSS encoding is very difficult and error prone. If something is missing in the library, please file a bug.
- Prefer a validator to an encoder: Some situations, such as href and src attributes, MUST use a validator
- Customize your error pages: Error pages can be customized for CQ. This should always mandatorily be done by developers. This is critical, so that the instance does not reveal sling traces on internal server errors.
- Do not tamper with the /libs path: You must not change anything in the /libs path. This is because the content of /libs is overwritten the next time you upgrade your instance (and may well be overwritten when you apply either a hotfix or feature pack).
- Keep template count low: Keep the number of templates low - as low as the number of fundamentally different page structures on the web sites.
Security:
- XSS Security - Web application firewall: Apart from the developers taking advantage of the XSSApi and protecting against XSS at code level, a web application firewall, such as mod_security for Apache, can provide reliable, central control over the security of the deployment environment and protect against previously undetected cross-site scripting attacks.
- Secure Communication for confidential Information: As for any internet application, make sure that when transporting confidential information
- traffic is secured through SSL
- HTTP POST is used if applicable
This applies to information that is confidential to the system (like configuration or administrative access) as well as information confidential to its users (like their personal details).
- Change Default Passwords: An out-of-the-box installation of CQ includes various accounts to enable you to administrate and use the instance. In particular, Adobe strongly recommends that after installation you change the passwords for the privileged (admin) account(s). In addition, Adobe recommends changing the OSGi (web) console password to something other than the admin. Adobe also recommends that you either remove the example user author, or (at minimum) disable it by changing the password.
- Uninstall example content and users: All example content and users should be uninstalled completely on a productive system before making it publicly accessible. Uninstall the cq-geometrixx-all-pkg-5.6.12.zip package.
- Disable CRXDE Support: CRXDE Support should be disabled on the production instance before making it publicly accessible. The Adobe CRXDE Support (com.day.crx.crxde-support) OSGi bundle should be disabled on both author and publish productive systems before making them accessible.
- Configure replication and transport users: Create users with specific, restricted access rights for building replication content (Author environment) and for receiving content (Publish environments) instead of using the admin user. The transport user should not be the admin user. Rather, set up a user on the publish system that has only access rights to the relevant portions of the publish system and use that user's credentials for the transport. You can start from the bundled replication-receiver user and configure this user's access rights to match your situation. The replication user should also not be the admin user, but a user who can only see content that is supposed to be replicated. The replication user is used to collect the content to be replicated on the author system before it is sent to the publisher.
- Disable WebDAV: CRX and CQ come with WebDAV support that lets you display and edit the repository content. Setting up WebDAV gives you direct access to the content repository through your desktop. WebDAV: should be disabled on the publish environment. On the Felix Management Console, find "Apache Sling Simple WebDAV Access to repositories (org.apache.sling.jcr.webdav)" & "Apache Sling DavEx Access to repositories (org.apache.sling.jcr.davex)". STOP both these bundles.
- Dispatcher: Use the Latest Version of Dispatcher. When using Dispatcher, you should install the latest available version that is available for your platform. On a yearly basis, you should upgrade your Dispatcher instance to use the latest version to take advantage of product and security enhancements.
- Restrict Access via the Dispatcher: The Dispatcher filter can be used to allow or deny external access to specific areas of CQ. To protect your instance you should configure the Dispatcher to restrict external access as far as possible. Only the following are available to external visitors:
- /content
- miscellaneous content such as designs and client libraries; for example: /etc/designs/default* , /etc/designs/mydesign*
- Preventing Denial of Service (DoS) Attacks: A denial of service (DoS) attack is an attempt to make a computer resource unavailable to its intended users. This is often done by overloading the resource. There are a few methods that can be used with CQ to help prevent such attacks. Ensure that you have installed the latest Security Hotfix. There are also ways of Configuring Sling to prevent DoS as well as ways of Configuring the Dispatcher to prevent DoS. See Dev Day documentation for details.
- Default Access to User Profile(s) is everyone: By default, everyone (the built-in group) has read access to all user profile(s). If such access is not appropriate for your installation you can change these default settings.
- Issues with Cross-Site Request Forgery (CSRF): This is a security issue from the CRX Security Checklist that is also appropriate to CQ. To address known security issues with (CSRF) in CRX WebDAV and Apache Sling you can configure the Referrer filter.
- Disable the CQ WCM Debug Filter on production systems: This is useful when developing as it allows the use of suffixes, but should be disabled on a production instance to ensure performance and security.
- Clickjacking: Configuring your webserver on lines of preventing clickjacking. To prevent clickjacking we recommend that you configure your webserver to provide the X-FRAME-OPTIONS HTTP header set to SAMEORIGIN.
- Access to Cloud Service Information: Reviewing whether the default security on the Cloud Service Information matches your requirements is recommended.
- OSGI Settings: Changing some OSGI settings on the publish instances can help avoid internal information leak to the public.
- Day CQ HTML Library Manager:
- enable Minify (to remove CRLF and whitespace characters).
- enable Gzip (to allow files to be gzipped and accessed with one request).
- disable Debug
- disable Timing
- Day CQ WCM Debug Filter:
- uncheck Enable
- Day CQ WCM Filter:
- set WCM Mode to "disabled"
- Apache Sling Java Script Handler:
- disable Generate Debug Info
- Apache Sling JSP Script Handler:
- disable Generate Debug Info
- disable Mapped Content
Presentation & Design:
Always make use of & exploit the CQ ClientLibs feature: Avoid inline javascript & CSS. If you want to display elements from a combination of CSS and JavaScript files on your CQ page, use the <cqIncludeClientLib> tag. This tag is a convenience wrapper around the com.day.cq.widget.HtmlLibraryManager service interface. Do not define CSS styling inside components JSP. This practice keeps components loosely coupled from a styling standpoint and lets you restyle them whenever necessary. Also, define a convention for naming HTML elements, so that you can modify them through external CSS files. Same applies for javascript as well. If some JavaScript code is common to all components, move it to a dedicated JavaScript file at the design level under etc/designs/<appname>.
- Make author friendly & futuristic components: Provide necessary flexibility and configuration capabilities to your custom components.
- Access Control to Parsys Design: Always exploit the access control to paragraph system design for uniformity and brand protection. Define access right to the Design mode of the paragraph systems, so that only authorized people (usually the administrator) can change them.
- When creating a template, keep main body within a parsys called “par”:Most or all templates will contain one or more paragraph systems to contain our components. One parsys is typically considered to be more prominent on the page, therefor considered the "main body" of content. This parsys name should always be "par". The reason for this is the "reference" component. This component allows an Author to browse the site and select a component from another page. The component will make the component appear on the referring page as though it were physically authored on that page. The bad part of this is it can only select a component on pages that contain a paragraph system named "par". If any other name is chosen, you will not be able to select component from within that parsys for inclusion using the "reference" component. Well you don’t want to be bothered by this, you can always create your own custom reference component.
- Float Css: Be careful with float css, it upsets the ExtJS based author system. It can cause elements to overlap. It can also make it hard to click on elements to edit them. You might need to add css clear styles to subsequent elements to make things work.
- Use resourceResolver.map: on all links in javascript and linked resources such as images – the link rewriter only does .html links and skips script blocks. This is essential if you want to do any kind of remapping of content.
- Control & Minimize open files in Java Process: Each java process may access files - this requires system resources. As CQ can access a large number of files it is recommended that the number of open files for a Java process be explicitly configured for CQ. This is for the Admin to take care. In case of developers, they should ensure that any file opened is correctly closed as soon as (meaningfully) possible.
Solution and Architecture:
- Avoid using JSP Scriptlets (<% %> and <%! %>), depend upon JSTL, EL / custom EL functions and JavaBeans: In some cases, some amount of Scriptlet code is required and unavoidable. However, keep it to a minimum. Scriptlet DOES NOT facilitate:
a) Readability
b) Testability
c) Maintainability
d) Extensibility / Reusability - If you must write Java code, and it will not be reused anywhere, and it makes no sense to write a JavaBean to handle the logic, use a scriptlet.
- Application level initializations at one place only: Unify application-level initialization in a single place. Ensure that common variables—such as user account information and session variables—are not initialized repeatedly at a component level. These variables should be initialized only once per page request.
- Use JCR Queries only in case of:
- Real end user queries such as fulltext searches on content
- Occasions where structured content needs to be found across the entire repository. In such cases, make sure that queries only run when absolutely required, e.g. on component activation or cache invalidation (as opposed to e.g. Workflows Steps, Event Handlers that trigger on content modifications, Filters, etc).
- DO NOT Use JCR Queries for pure rendering requests: JCR Queries are not appropriate for:
- Rendering navigation.
- Creating a "top 10 latest news items" overview.
- Showing counts of content items.
- The Query Builder API generates JCR Queries under the hood. So if you see Query Builder in code, it means you have used JCR Query. For rendering content, use navigational access to the content tree instead of performing a JCR Query.
- When you need the session object, use the user session: You should use the user session, not the administrative session. This means you should use: getResourceResolver().adaptTo(Session.class);
- Avoid using loginAdministrative: Do you really need to run some code as superuser or is it more appropriate to use the contextual user? Remember that ‘admin’ can do anything and see everything, so you lose any security control over the situation. You also lose any audit of changes, as they will be logged as ‘admin’. In general, if you create a repository session, you are responsible for closing that session. If you didn’t create it you can assume that it will be closed later by the framework.
- Don’t forget Logout: If using login or loginAdministrative, use logout. You need to remember to end any sessions created with ‘loginAdministrative’, otherwise you have a session leak and will run out of resources. If you are not using loginAdministrative, don’t logout. You shouldn’t close sessions which you haven’t explicitly created. Their lifecycle is managed by Sling.
- Call ungetService: Every call to getService should have an ungetService call. Each get call increments a counter and if we don’t decrement the reference count it will not be able to release the service, potentially wasting resources.
- Be careful with OptingServlet & Filter interfaces: If you are implementing servlets, be careful with implementing OptingServlet & Filter interfaces – they can break the POST requests needed by CRXDE.
- Exception Handling: Exceptions behave differently in CQ5 author and CQ5 publish, so make sure to use try/catch, value checking, and good exception handling practices. Make all your components fail independently, and not fail the whole page.
Digital Assets & Media:
- Create and Use a Naming Convention: If you create a specific strategy for how your original files are named — and stick to it — you will be able to more easily identify, locate and share your files. You may consider including pertinent file information such as client name, project, product number, and date into the file name. Try to keep the file names short for optimum readability, but avoid unclear abbreviations.
- Have your files organized in a coherent and understandable way: With any large number of files, setting up an effective folder hierarchy is practically a necessity. Files can be organized into one root directory. For example create an “images” directory as root directory with as many subdirectories as desired. This can be an important organizational method. In general it’s best to start with a simplistic folder structure and don’t overcomplicate things by creating a hi-level of granularity. When creating a folder structure, consider how this can expand to accommodate various files that you will create in the future.
- Metadata is the king of DAM: With any large numberLike in case of websites content is king, in case of a DAM asset metadata is the king. Consider this challenge. If you have millions of assets, and you only have one minute to find a particular asset, which option would you prefer? (1) searching using metadata, or (2) visually flipping through millions of previews until you find the asset you need? A DAM system is only as good as the metadata you put into it. In other words: garbage in, garbage out. Metadata is the key driver of a DAM system. Consider all users who will be accessing your assets, and ensure that the appropriate metadata is extracted and applied to files in your asset manager.
- Make sure to allow display and manipulation of metadata of the assets. Allow metadata to be embedded back into your original files so that information is never lost.
- Tag Assets: Tagging you assets is another great way to organize assets. It also facilitates faster searching of assets.
Generic:
- Get everyone to agree upon component and template property name patterns, as well as JSP naming patterns: Like variable names, property naming styles can vary wildly at developer discretion if some standard is not set. This can make property name usage difficult and confusing. Deciding ahead of time will circumvent people making up their own naming standards which may or may not be easy to use.
- Use the power of the system: Maximize use of the power and flexibility of CQ paragraph system - the parsys & iparsys components.
- Keep business logic independent of presentation: While planning and developing your components, keep the business logic independent of the user interface layer (JSP). Move the business logic in a separate class, so that you can reuse it in other parts of the application. This distinction between the user interface and business logic aids application maintenance. Break down logic into services and move as much code out of the JSP as possible into OSGi bundles. It’s much easier to test OSGi bundles and makes the JSPs far easier to read. It’ll also allow you to reuse the services as development progresses. Also, in cases where different business logic is required for different components, you can extend existing classes to quickly add the required functionality.
As a practice keep the number of non-comment lines in a JSP to about 30.
- Define the allowed components: in the given paragraph system so that editors can then place the required components on the page. In our case it could be a list component, which can traverse a subtree of pages and extract the information according to predefined rules.
- Nulls are always a possibility: It’s possible to create components without editing them by dragging them from the sidekick to the page. This doesn’t set any data so make sure your code assumes that null is a possible value.
'Develop > AEM' 카테고리의 다른 글
AEM 6.x Server Setting (0) | 2016.11.09 |
---|---|
특정 node 값 받아오기 (0) | 2016.11.07 |
어플리케이션/프로젝트는 무엇입니까? (0) | 2016.10.24 |
Adobe EXPERIENCE MANAGEMENT CQ Developer Tricks (0) | 2016.10.24 |
aem 403 Sling Post servlet (0) | 2016.10.24 |