Drupal Feeds

Commerce Url Hash

Latest Drupal Modules - Thu, 2017-06-22 08:05
Categories: Straight From Drupal

SEO friendly URL redirect

Latest Drupal Modules - Thu, 2017-06-22 05:52

This module aims to add all URL redirection rules to promote SEO friendliness in Drupal project URLs.

Categories: Straight From Drupal

Entity Print Form Display

Latest Drupal Modules - Thu, 2017-06-22 04:47

This module leverages entity_print module and allows you to print an entity via a form display (as opposed to a view display).

Full description to come.

Categories: Straight From Drupal

PageMaker

Latest Drupal Modules - Wed, 2017-06-21 21:38
Categories: Straight From Drupal

Why Financial Services Needs Drupal 8 to Innovate

Acquia Blogs - Wed, 2017-06-21 19:31

Why financial services needs Drupal 8 to innovate

The wave of digital disruption continues to travel from sector to sector. Outside of market trading technology, financial services organizations have a decades﹣long history of innovating very little due to regulatory compliance concerns and in turn keeping legacy technology in market that is past its prime. But every year the number of consumers that grew up with technology steadily increases ﹣an unstoppable force driving digital transformation across every industry.

This increasingly large number of digital natives has finally begun to exert pressure on one of the most regulated sectors in the US economy: financial services. In this need to rapidly innovate, modernize and deliver the kind of experience consumers are expecting, these organizations need to turn to and will find great success with Drupal 8.

Take a recent example: While the specific brand cannot be shared publicly, this company is one of the world’s largest leveraged buyout organizations, having owned many iconic American brands over the years. With a portfolio valued in the billions and a highly successful track record, this organization is among the highest caliber investment companies in the world. But their digital brand did not match this reality. This is where Drupal 8 comes in.

With a rapid rebrand and new, fully responsive design Third&Grove helped the client realize some immediate gains. We compared the performance of several key engagement metrics between the old site (Joomla) and the new Drupal 8 powered site, and the results were phenomenal:

  • Total traffic up 66%
  • Unique users up 53%
  • Time on site up 44%
  • Total pages visited up 97%
  • Pages per visit up 19%
  • Bounce rate down 21%

How did we achieve such startling improvement? Drupal 8 made a variety of refinements possible:

  1. With strong support for SEO and responsive design out of the box, search engine rankings were dramatically improved, and so, in turn, was traffic.
  2. By using a unique process that was both user-centered and data-driven, it was seamless to steer the client towards a design that improved customer engagement rather than hindered it (think story carousels of regret).
  3. Drupal 8’s awesome support for in-place editing made it easy for marketing to refine content to maximize engagement, instead of being a dreaded process of logging into the cumbersome editorial backend of doom.
  4. Being open source we could leverage Drupal 8’s large ecosystem of free modules that provide additional functionality so that the project budget could be focused on improving engagement rather than building features from scratch.

The pressure for increased digital innovation in the financial services sector continues to grow, and Drupal 8 continues to deliver. But the track record isn’t just isolated to marketing sites. Nasdaq chose Drupal 8 to power their investor relations site platform which is leveraged by some of the largest companies in the world. With such a strong value proposition and demonstrated track record of success, Drupal 8 is emerging as a digital content and experience management system of choice in financial services.

Categories: Drupal Universe

Abra

Latest Drupal Modules - Wed, 2017-06-21 16:35

Economic system ABRA Gen.

Categories: Straight From Drupal

DeliBarry

Latest Drupal Modules - Wed, 2017-06-21 16:31

Czech delivery system DeliBarry.com

Categories: Straight From Drupal

OpenID OpenID Connect Migrate

Latest Drupal Modules - Wed, 2017-06-21 16:17

OpenID to OpenID Connect migration.

Categories: Straight From Drupal

Login and Register Via Mobile Number

Latest Drupal Modules - Wed, 2017-06-21 11:27

SignIn & SignUp Via Mobile Number

Categories: Straight From Drupal

Api.AI Webhook

Latest Drupal Modules - Wed, 2017-06-21 11:04

This module integrates your Drupal website with Api.AI Webooks, letting your Api.AI agents talk with you website, respond to Intents request and filling slots.

Categories: Straight From Drupal

Flocon de toile | Freelance Drupal: Do I have to wait for Drupal 9 for my web project?

Planet Drupal - Wed, 2017-06-21 10:00

In a previous post, we saw the Drupal 8's new policies for versioning, support and maintenance for its minor and major versions. This policy has evolved somewhat since the last DrupalCon Baltimore conference in April 2017. And this evolution of Drupal's strategy deserves a little attention because it can bring new light to those who hesitate to migrate their site on Drupal 8. Or those who are wondering about the relevance of launching their web project on Drupal 8.

Flocon de toile | Freelance Drupal: Do I have to wait for Drupal 9 for my web project?

Feeds from Drupal.org - Wed, 2017-06-21 10:00

In a previous post, we saw the Drupal 8's new policies for versioning, support and maintenance for its minor and major versions. This policy has evolved somewhat since the last DrupalCon Baltimore conference in April 2017. And this evolution of Drupal's strategy deserves a little attention because it can bring new light to those who hesitate to migrate their site on Drupal 8. Or those who are wondering about the relevance of launching their web project on Drupal 8.

Categories: Straight From Drupal

Dropsolid: Drupal 8 and React Native

Planet Drupal - Wed, 2017-06-21 09:57
21 Jun Drupal 8 and React Native Niels A Drupal 8 Tech Drupal

One day you might wake up with the next big idea that will shake the world in the most ungentle way. You decide to build an app, because you’ll have full access to all features of the device that you want your solution to work on. But then it dawns on you: you will actually need to build multiple apps in completely different languages while finding a way for them to serve the same content...

Then you start to realise that you won’t be able to step into the shoes of the greats, because web technology is holding you back. Fortunately, Drupal 8 and React Native are here to save your day - and your dream!

In this blog post you'll read how you can leverage Drupal 8 to serve as the back-end for your React Native app. 

First, however, a quick definition of what these technologies are:

  • Drupal is an open source content management system based on PHP.
  • React Native is a framework to build native apps using JavaScript and React.

If you want to read more about Drupal 8 or React Native, you're invited to check the sources at the bottom of this article.
 

Why React Native?

There are a myriad of front-end technologies available to you these days. The most popular ones are Angular and React. Both technologies allow you to build apps, but there is a big difference in how the apps will be built.

The advantage of employing React Native is that it lets you build an app using JavaScript, while converting the JavaScript into native code. In contrast, Angular or Ionic allow you to create a hybrid app, which basically is a website that gets embedded in a web view. Although the benefit here is that you're able to access the native features of a device.

In this case, we prefer React Native, because we want to build iOS and Android applications that run natively.
 

Headless Drupal

One of the big buzzwords that's been doing the rounds in the Drupal community lately is 'Headless'. A headless Drupal is actually a Drupal application where the front-end is not served by Drupal, but by a different technology.

You still get the benefits of a top notch and extremely flexible content management system, but you also get the benefits of your chosen front-end technology.

In this example, you'll discover how to set up a native iOS and Android application that gets its data from a Drupal website. To access the information, users will have to log in to the app, which allows the app to serve content tailored to the preferences of the user. Crucial in the current individualized digital world.

 

Drupal 8 - React Native Android & iOS

So this already brings us to our first hurdle. Because we are using a native application, authenticating users through cookies or sessions is not possible. So we are going to show you how to prepare your React Native application and your Drupal site to accept authenticated requests.
 

The architecture

The architecture consists of a vanilla Drupal 8 version and a React Native project with Redux.

The implemented flow is as following:

  1. A user gets the login screen presented on the app.
  2. The user fills in his credentials in the form
  3. The app posts the credentials to the endpoint in Drupal
  4. Drupal validates the credentials and logs the user in
  5. Drupal responds with a token based on the current user
  6. The app stores the token for future use
  7. The app now uses the token for all other requests the app makes to the Drupal REST API.
     
Creating an endpoint in Drupal

First we had to choose our authentication method. In this example, we opted to authenticate using a JWT or JSON web token, because there already is a great contributed module available for it on Drupal.org (https://www.drupal.org/project/jwt).

This module provides an authentication service that you can use with the REST module that is now in Drupal 8 core. This authentication service will read the token that is passed in the headers of the request and will determine the current user from it. All subsequent functionality in Drupal will then use that user to determine if it has permission to access the requested resources. This authentication service works for all subsequent requests, but not for the original request to get the JWT.

The original endpoint the JWT module provides, already expects the user to be logged in before it can serve the token. You could use the ready available basic authentication service, but we preferred to build our own as an example.
 

Authentication with JSON post

Instead of passing along the username and password in the headers of the request like the basic authentication service expects, we will send the username and password in the body of our request formatted as JSON.

Our authentication class implements the AuthenticationProviderInterface and is announced in json_web_token.services.yml as follows:

services: authentication.json_web_token: class: Drupal\json_web_token\Authentication\Provider\JsonAuthenticationProvider arguments: ['@config.factory', '@user.auth', '@flood', '@entity.manager'] tags: - { name: authentication_provider, provider_id: 'json_authentication_provider', priority: 100 }

The interface states that we have to implement two methods, applies and authenticate:

public function applies(Request $request) { $content = json_decode($request->getContent()); return isset($content->username, $content->password) && !empty($content->username) && !empty($content->password); }

Here we define when the authenticator should be applied. So our requirement is that the JSON that is posted contains a username and password. In all other cases this authenticator can be skipped. Every authenticator service you define will always be called by Drupal. Therefore, it is very important that you define your conditions for applying the authentication service.

public function authenticate(Request $request) { $flood_config = $this->configFactory->get('user.flood'); $content = json_decode($request->getContent()); $username = $content->username; $password = $content->password; // Flood protection: this is very similar to the user login form code. // @see \Drupal\user\Form\UserLoginForm::validateAuthentication() // Do not allow any login from the current user's IP if the limit has been // reached. Default is 50 failed attempts allowed in one hour. This is // independent of the per-user limit to catch attempts from one IP to log // in to many different user accounts. We have a reasonably high limit // since there may be only one apparent IP for all users at an institution. if ($this->flood->isAllowed(json_authentication_provider.failed_login_ip', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) { $accounts = $this->entityManager->getStorage('user') ->loadByProperties(array('name' => $username, 'status' => 1)); $account = reset($accounts); if ($account) { if ($flood_config->get('uid_only')) { // Register flood events based on the uid only, so they apply for any // IP address. This is the most secure option. $identifier = $account->id(); } else { // The default identifier is a combination of uid and IP address. This // is less secure but more resistant to denial-of-service attacks that // could lock out all users with public user names. $identifier = $account->id() . '-' . $request->getClientIP(); } // Don't allow login if the limit for this user has been reached. // Default is to allow 5 failed attempts every 6 hours. if ($this->flood->isAllowed('json_authentication_provider.failed_login_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) { $uid = $this->userAuth->authenticate($username, $password); if ($uid) { $this->flood->clear('json_authentication_provider.failed_login_user', $identifier); return $this->entityManager->getStorage('user')->load($uid); } else { // Register a per-user failed login event. $this->flood->register('json_authentication_provider.failed_login_user', $flood_config->get('user_window'), $identifier); } } } } // Always register an IP-based failed login event. $this->flood->register('json_authentication_provider.failed_login_ip', $flood_config->get('ip_window')); return []; }

Here we mostly reimplemented the authentication functionality of the basic authorization service, with the difference that we read the data from a JSON format. This code logs the user into the Drupal application. All the extra code is flood protection.

Getting the JWT token

To get the JWT token we leveraged the REST module, and created a new rest resource plugin. We could have used the endpoint the module already provides, but we prefer to create all our endpoints with a version in it. We defined the plugin with the following annotation:

/** * Provides a resource to get a JWT token. * * @RestResource( * id = "token_rest_resource", * label = @Translation("Token rest resource"), * uri_paths = { * "canonical" = "/api/v1/token", * "https://www.drupal.org/link-relations/create" = "/api/v1/token" * } * ) */

The uri_paths are the most important part of this annotation. By setting both the canonical and the weird looking Drupal.org keys, we are able to set a fully custom path for our endpoint. That allows us to set the version of our API in the URI like this: /api/v1/token. This way we can easily roll out new versions of our API and clearly communicate about deprecating older versions.

Our class extends the ResourceBase class provided by the REST module. We only implemented a post method in our class, as we only want this endpoint to handle posts.

public function post() { if($this->currentUser->isAnonymous()){ $data['message'] = $this->t("Login failed. If you don't have an account register. If you forgot your credentials please reset your password."); }else{ $data['message'] = $this->t('Login succeeded'); $data['token'] = $this->generateToken(); } return new ResourceResponse($data); } /** * Generates a new JWT. */ protected function generateToken() { $token = new JsonWebToken(); $event = new JwtAuthIssuerEvent($token); $this->eventDispatcher->dispatch(JwtAuthIssuerEvents::GENERATE, $event); $jwt = $event->getToken(); return $this->transcoder->encode($jwt, array()); }

The generateToken method is a custom method where we leverage the JWT module to get us a token that we can return. 
 
We do not return a JSON object directly. We return a response in the form of an array. This is a very handy feature of the REST module, because you can choose the formats of your endpoint using the interface in Drupal. So you could easily return any other supported format like xml, JSON or hal_json. For this example, we chose hal_json. 

Drupal has some built-in security measures for non-safe methods. The only safe methods are HEAD, GET, OPTIONS and TRACE. We are implementing a non-safe method, so we have to take into account the following things:

  • When the app does a post it also needs to send a X-CSRF-Token in the header to avoid cross site request forgery. This token can be gotten from /session/token endpoint.
  • In case of a POST we also need to set the Content-type request header to “application/hal+json” on top of the query parameter “_format=hal_json”.
Putting things together

The only thing left is to enable our endpoint through the interface that the rest modules provides on /admin/config/services/rest.

Drupal 8 & React Native - REST resources - Drupal blog

As you can see, we’ve configured our token endpoint with our custom json_authentication_provider service and it is available in hal_json and json formats.

Calling the endpoint in our React Native application The login component

Our login component contain two input fields and a button.

this.setState({username})} placeholderTextColor="#FFF" style={styles.input} /> this.setState({password})} style={styles.input} /> this.login({ username: this.state.username, password: this.state.password })} > Get Started

When we click the login button we trigger the login action that is defined in our bindActions function.

function bindActions(dispatch) { return { login: (username, password) => dispatch(login(username, password)), }; }

The login action is defined in our auth.js:

import type { Action } from './types'; import axios from 'react-native-axios'; export const LOGIN = 'LOGIN'; export function login(username, password):Action { var jwt = ''; var endpoint = "https://example.com/api/v1/token?_format=hal_json"; return { type: LOGIN, payload: axios({ method: 'post', url: endpoint, data: { username: username, password: password, jwt: jwt, }, headers: { 'Content-Type':'application/hal+json', 'X-CSRF-Token':'V5GBdzli7IvPCuRjMqvlEC4CeSeXgufl4Jx3hngZYRw' } }) } }

In this example, we set the X-CSRF-token fixed to keep it simple. Normally you would get this first. We’ve also used the react-native-axios package to handle our post. This action will return a promise. If you use the promise and thunk middleware in your Redux Store you can set up your reducer in the following way.

import type { Action } from '../actions/types'; import { LOGIN_PENDING, LOGOUT} from '../actions/auth'; import { REHYDRATE } from 'redux-persist/constants'; export type State = { fetching: boolean, isLoggedIn: boolean, username:string, password:string, jwt: string, error: boolean, } const initialState = { fetching: false, username: '', password: '', error: null, } export default function (state:State = initialState, action:Action): State { switch (action.type) { case "LOGIN_PENDING": return {...state, fetching: true} case "LOGIN_REJECTED": return {...state, fetching: false, error: action.payload} case "LOGIN_FULFILLED": return {...state, fetching: false, isLoggedIn: true, jwt:action.payload.data.token} case "REHYDRATE": var incoming = action.payload.myReducer if (incoming) return {...state, ...incoming, specialKey: processSpecial(incoming.specialKey)} return state default: return state; } }

The reducer will be able to act on the different action types of the promise:

  • LOGIN_PENDING: Allows you to change the state of your component so you could implement a loader while it is trying to get the token.
  • LOGIN_REJECTED: When the attempt fails you could give a notification why it failed.
  • LOGIN_FULFILLED: When the attempt succeeds you have the token and set the state to logged in.

So once we had implemented all of this, we had an iOS and Android app that actually used a Drupal 8 site as it main content store.

Following this example, you should be all set up to deliver tailored content to your users on whichever platform they may be.

The purpose of this article was to demonstrate how effective Drupal 8 can be as a source for your upcoming iOS or Android application.
 

Useful resources:

 

More articles by our Dropsolid Technical Leads, strategist and marketeers? Check them out here.

Dropsolid: Drupal 8 and React Native

Feeds from Drupal.org - Wed, 2017-06-21 09:57
21 Jun Drupal 8 and React Native Niels A Drupal 8 Tech Drupal

One day you might wake up with the next big idea that will shake the world in the most ungentle way. You decide to build an app, because you’ll have full access to all features of the device that you want your solution to work on. But then it dawns on you: you will actually need to build multiple apps in completely different languages while finding a way for them to serve the same content...

Then you start to realise that you won’t be able to step into the shoes of the greats, because web technology is holding you back. Fortunately, Drupal 8 and React Native are here to save your day - and your dream!

In this blog post you'll read how you can leverage Drupal 8 to serve as the back-end for your React Native app. 

First, however, a quick definition of what these technologies are:

  • Drupal is an open source content management system based on PHP.
  • React Native is a framework to build native apps using JavaScript and React.

If you want to read more about Drupal 8 or React Native, you're invited to check the sources at the bottom of this article.
 

Why React Native?

There are a myriad of front-end technologies available to you these days. The most popular ones are Angular and React. Both technologies allow you to build apps, but there is a big difference in how the apps will be built.

The advantage of employing React Native is that it lets you build an app using JavaScript, while converting the JavaScript into native code. In contrast, Angular or Ionic allow you to create a hybrid app, which basically is a website that gets embedded in a web view. Although the benefit here is that you're able to access the native features of a device.

In this case, we prefer React Native, because we want to build iOS and Android applications that run natively.
 

Headless Drupal

One of the big buzzwords that's been doing the rounds in the Drupal community lately is 'Headless'. A headless Drupal is actually a Drupal application where the front-end is not served by Drupal, but by a different technology.

You still get the benefits of a top notch and extremely flexible content management system, but you also get the benefits of your chosen front-end technology.

In this example, you'll discover how to set up a native iOS and Android application that gets its data from a Drupal website. To access the information, users will have to log in to the app, which allows the app to serve content tailored to the preferences of the user. Crucial in the current individualized digital world.

 

Drupal 8 - React Native Android & iOS

So this already brings us to our first hurdle. Because we are using a native application, authenticating users through cookies or sessions is not possible. So we are going to show you how to prepare your React Native application and your Drupal site to accept authenticated requests.
 

The architecture

The architecture consists of a vanilla Drupal 8 version and a React Native project with Redux.

The implemented flow is as following:

  1. A user gets the login screen presented on the app.
  2. The user fills in his credentials in the form
  3. The app posts the credentials to the endpoint in Drupal
  4. Drupal validates the credentials and logs the user in
  5. Drupal responds with a token based on the current user
  6. The app stores the token for future use
  7. The app now uses the token for all other requests the app makes to the Drupal REST API.
     
Creating an endpoint in Drupal

First we had to choose our authentication method. In this example, we opted to authenticate using a JWT or JSON web token, because there already is a great contributed module available for it on Drupal.org (https://www.drupal.org/project/jwt).

This module provides an authentication service that you can use with the REST module that is now in Drupal 8 core. This authentication service will read the token that is passed in the headers of the request and will determine the current user from it. All subsequent functionality in Drupal will then use that user to determine if it has permission to access the requested resources. This authentication service works for all subsequent requests, but not for the original request to get the JWT.

The original endpoint the JWT module provides, already expects the user to be logged in before it can serve the token. You could use the ready available basic authentication service, but we preferred to build our own as an example.
 

Authentication with JSON post

Instead of passing along the username and password in the headers of the request like the basic authentication service expects, we will send the username and password in the body of our request formatted as JSON.

Our authentication class implements the AuthenticationProviderInterface and is announced in json_web_token.services.yml as follows:

services: authentication.json_web_token: class: Drupal\json_web_token\Authentication\Provider\JsonAuthenticationProvider arguments: ['@config.factory', '@user.auth', '@flood', '@entity.manager'] tags: - { name: authentication_provider, provider_id: 'json_authentication_provider', priority: 100 }

The interface states that we have to implement two methods, applies and authenticate:

public function applies(Request $request) { $content = json_decode($request->getContent()); return isset($content->username, $content->password) && !empty($content->username) && !empty($content->password); }

Here we define when the authenticator should be applied. So our requirement is that the JSON that is posted contains a username and password. In all other cases this authenticator can be skipped. Every authenticator service you define will always be called by Drupal. Therefore, it is very important that you define your conditions for applying the authentication service.

public function authenticate(Request $request) { $flood_config = $this->configFactory->get('user.flood'); $content = json_decode($request->getContent()); $username = $content->username; $password = $content->password; // Flood protection: this is very similar to the user login form code. // @see \Drupal\user\Form\UserLoginForm::validateAuthentication() // Do not allow any login from the current user's IP if the limit has been // reached. Default is 50 failed attempts allowed in one hour. This is // independent of the per-user limit to catch attempts from one IP to log // in to many different user accounts. We have a reasonably high limit // since there may be only one apparent IP for all users at an institution. if ($this->flood->isAllowed(json_authentication_provider.failed_login_ip', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) { $accounts = $this->entityManager->getStorage('user') ->loadByProperties(array('name' => $username, 'status' => 1)); $account = reset($accounts); if ($account) { if ($flood_config->get('uid_only')) { // Register flood events based on the uid only, so they apply for any // IP address. This is the most secure option. $identifier = $account->id(); } else { // The default identifier is a combination of uid and IP address. This // is less secure but more resistant to denial-of-service attacks that // could lock out all users with public user names. $identifier = $account->id() . '-' . $request->getClientIP(); } // Don't allow login if the limit for this user has been reached. // Default is to allow 5 failed attempts every 6 hours. if ($this->flood->isAllowed('json_authentication_provider.failed_login_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) { $uid = $this->userAuth->authenticate($username, $password); if ($uid) { $this->flood->clear('json_authentication_provider.failed_login_user', $identifier); return $this->entityManager->getStorage('user')->load($uid); } else { // Register a per-user failed login event. $this->flood->register('json_authentication_provider.failed_login_user', $flood_config->get('user_window'), $identifier); } } } } // Always register an IP-based failed login event. $this->flood->register('json_authentication_provider.failed_login_ip', $flood_config->get('ip_window')); return []; }

Here we mostly reimplemented the authentication functionality of the basic authorization service, with the difference that we read the data from a JSON format. This code logs the user into the Drupal application. All the extra code is flood protection.

Getting the JWT token

To get the JWT token we leveraged the REST module, and created a new rest resource plugin. We could have used the endpoint the module already provides, but we prefer to create all our endpoints with a version in it. We defined the plugin with the following annotation:

/** * Provides a resource to get a JWT token. * * @RestResource( * id = "token_rest_resource", * label = @Translation("Token rest resource"), * uri_paths = { * "canonical" = "/api/v1/token", * "https://www.drupal.org/link-relations/create" = "/api/v1/token" * } * ) */

The uri_paths are the most important part of this annotation. By setting both the canonical and the weird looking Drupal.org keys, we are able to set a fully custom path for our endpoint. That allows us to set the version of our API in the URI like this: /api/v1/token. This way we can easily roll out new versions of our API and clearly communicate about deprecating older versions.

Our class extends the ResourceBase class provided by the REST module. We only implemented a post method in our class, as we only want this endpoint to handle posts.

public function post() { if($this->currentUser->isAnonymous()){ $data['message'] = $this->t("Login failed. If you don't have an account register. If you forgot your credentials please reset your password."); }else{ $data['message'] = $this->t('Login succeeded'); $data['token'] = $this->generateToken(); } return new ResourceResponse($data); } /** * Generates a new JWT. */ protected function generateToken() { $token = new JsonWebToken(); $event = new JwtAuthIssuerEvent($token); $this->eventDispatcher->dispatch(JwtAuthIssuerEvents::GENERATE, $event); $jwt = $event->getToken(); return $this->transcoder->encode($jwt, array()); }

The generateToken method is a custom method where we leverage the JWT module to get us a token that we can return. 
 
We do not return a JSON object directly. We return a response in the form of an array. This is a very handy feature of the REST module, because you can choose the formats of your endpoint using the interface in Drupal. So you could easily return any other supported format like xml, JSON or hal_json. For this example, we chose hal_json. 

Drupal has some built-in security measures for non-safe methods. The only safe methods are HEAD, GET, OPTIONS and TRACE. We are implementing a non-safe method, so we have to take into account the following things:

  • When the app does a post it also needs to send a X-CSRF-Token in the header to avoid cross site request forgery. This token can be gotten from /session/token endpoint.
  • In case of a POST we also need to set the Content-type request header to “application/hal+json” on top of the query parameter “_format=hal_json”.
Putting things together

The only thing left is to enable our endpoint through the interface that the rest modules provides on /admin/config/services/rest.

Drupal 8 & React Native - REST resources - Drupal blog

As you can see, we’ve configured our token endpoint with our custom json_authentication_provider service and it is available in hal_json and json formats.

Calling the endpoint in our React Native application The login component

Our login component contain two input fields and a button.

this.setState({username})} placeholderTextColor="#FFF" style={styles.input} /> this.setState({password})} style={styles.input} /> this.login({ username: this.state.username, password: this.state.password })} > Get Started

When we click the login button we trigger the login action that is defined in our bindActions function.

function bindActions(dispatch) { return { login: (username, password) => dispatch(login(username, password)), }; }

The login action is defined in our auth.js:

import type { Action } from './types'; import axios from 'react-native-axios'; export const LOGIN = 'LOGIN'; export function login(username, password):Action { var jwt = ''; var endpoint = "https://example.com/api/v1/token?_format=hal_json"; return { type: LOGIN, payload: axios({ method: 'post', url: endpoint, data: { username: username, password: password, jwt: jwt, }, headers: { 'Content-Type':'application/hal+json', 'X-CSRF-Token':'V5GBdzli7IvPCuRjMqvlEC4CeSeXgufl4Jx3hngZYRw' } }) } }

In this example, we set the X-CSRF-token fixed to keep it simple. Normally you would get this first. We’ve also used the react-native-axios package to handle our post. This action will return a promise. If you use the promise and thunk middleware in your Redux Store you can set up your reducer in the following way.

import type { Action } from '../actions/types'; import { LOGIN_PENDING, LOGOUT} from '../actions/auth'; import { REHYDRATE } from 'redux-persist/constants'; export type State = { fetching: boolean, isLoggedIn: boolean, username:string, password:string, jwt: string, error: boolean, } const initialState = { fetching: false, username: '', password: '', error: null, } export default function (state:State = initialState, action:Action): State { switch (action.type) { case "LOGIN_PENDING": return {...state, fetching: true} case "LOGIN_REJECTED": return {...state, fetching: false, error: action.payload} case "LOGIN_FULFILLED": return {...state, fetching: false, isLoggedIn: true, jwt:action.payload.data.token} case "REHYDRATE": var incoming = action.payload.myReducer if (incoming) return {...state, ...incoming, specialKey: processSpecial(incoming.specialKey)} return state default: return state; } }

The reducer will be able to act on the different action types of the promise:

  • LOGIN_PENDING: Allows you to change the state of your component so you could implement a loader while it is trying to get the token.
  • LOGIN_REJECTED: When the attempt fails you could give a notification why it failed.
  • LOGIN_FULFILLED: When the attempt succeeds you have the token and set the state to logged in.

So once we had implemented all of this, we had an iOS and Android app that actually used a Drupal 8 site as it main content store.

Following this example, you should be all set up to deliver tailored content to your users on whichever platform they may be.

The purpose of this article was to demonstrate how effective Drupal 8 can be as a source for your upcoming iOS or Android application.
 

Useful resources:

 

More articles by our Dropsolid Technical Leads, strategist and marketeers? Check them out here.

Categories: Straight From Drupal

[D7] Add js and css

Latest Drupal Modules - Wed, 2017-06-21 09:09

This modules helps you to add js and css either external or internal even inline as well. Very easy to use, having standard format to ass js and css. Just follow those standards and explore the module.

Categories: Straight From Drupal

Domain Google Tag

Latest Drupal Modules - Wed, 2017-06-21 08:41
Categories: Straight From Drupal

Get Tweets

Latest Drupal Modules - Wed, 2017-06-21 07:32

This module provides import tweets through Twitter API.

Registration with Twitter

Before you start the installation process you must register on Twitter and create your own application.
You will get "Consumer Key", "Consumer Secret".

Dependencies:

This module needs to be installed via Composer, which will download the required libraries.

Categories: Straight From Drupal

Commerce Simple Order System

Latest Drupal Modules - Wed, 2017-06-21 06:40

A better, more streamlined order creation system. The module re-invents the commerce ordering system so that admins can create and manage orders through a more easy-to-use interface. It provides the following features:

Categories: Straight From Drupal

Block In Page Not Found

Latest Drupal Modules - Wed, 2017-06-21 05:51
What's "Block In Page Not Found" ?

This module provide the ability to place a block in 404 page or page not found.

How to use this module ?

After the installation, You should go to /admin/structure/block and then to configure an enabled block , you will have the ability to check on "Show in page not found".

Please provide feedback and ideas to improve it !

Categories: Straight From Drupal

Sendgrid headers

Latest Drupal Modules - Tue, 2017-06-20 22:01

This module provides a UI for overriding Sendgrid mail headers.
It will only works if you connect to Sendgrid thru postfix.

Categories: Straight From Drupal

Pages

Subscribe to My Drupal aggregator