Has anyone integrated Ionic and Drupal 7 and above login?

There are several sample apps which shows Ionic 3 “reading” drupal backend using simple Json feed. But has anyone able to integrate Drupal7 login/logout using Iionic 3? All the example on the net are using ionic 1

Hello, I was able to implement login/logout to Drupal 7 backend, both using Angular Http and a bit painfully using native Http modules.

Although the implementation is a bit hacky, here a working sample provider using Angular Http:

src/providers/drupal/drupal.ts

import {Injectable} from '@angular/core';
import {Http, RequestOptions, URLSearchParams} from '@angular/http';

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/timeout';
import 'rxjs/add/operator/do';

@Injectable()
export class DrupalProvider {
    public loginStatus: boolean;

    private baseUrl = 'https://example.com'; // This is your backends base url
    private requestTimeout = 30 * 1000; // 30 seconds

    constructor(public http: Http) {}

    /**
     * Makes a GET request to the given endpoint.
     * @param {string} endpoint
     * @param params
     * @param {RequestOptions} options
     * @returns {Observable<any>}
     */
    public get(endpoint: string, params?: any, options?: RequestOptions) {
        options = options || new RequestOptions();

        // We always want to send the credentials
        options.withCredentials = true;

        if (params) {
            let searchParams = this.createSearchParams(params);
            options.params = !options.params && searchParams || options.params;
        }

        return this.http.get(this.baseUrl + '/' + endpoint, options)
            .timeout(this.requestTimeout);
    }

    /**
     * Makes a POST request to the given endpoint.
     * @param {string} endpoint
     * @param body
     * @param {RequestOptions} options
     * @returns {Observable<Response>}
     */
    public post(endpoint: string, body: any, options?: RequestOptions) {
        options = options || new RequestOptions();

        // We always want to send the credentials
        options.withCredentials = true;

        return this.http.post(this.baseUrl + '/' + endpoint, body, options)
            .timeout(this.requestTimeout);
    }

    /**
     * Login to the backend.
     * @param credentials Object with username and password properties.
     * @returns {Observable<boolean>}
     */
    public login(credentials: {username: string, password: string}) {
        let url = 'user/login';

        return this.get(url)
            .map(resp => this.getFormToken(resp.text()))
            .mergeMap(tokens => this.postLoginForm(credentials, tokens))
            .map(resp => this.checkLoginResponse(resp.text()))
            .do(status => this.loginStatus = status === true);
    }

    /**
     * Logout from the backend.
     */
    public logout() {
        let url = 'user/logout';
        return this.get(url)
            .map(resp => this.checkLoginResponse(resp.text()))
            .do(status => this.loginStatus = status === true);
    }

    /**
     * Check login status. This function can be used i. e. on the app start.
     */
    public checkLoginStatus() {
        return this.get('').map(resp => this.checkLoginResponse(resp.text()))
            .subscribe(status => this.loginStatus = status === true);
    }

    /**
     * Gets CSRF token from html, and adds it with form id to the credentials.
     * @param {string} html
     * @returns {any}
     */
    private getFormToken(html) {
        let formTokenFields = {};

        let matches = html.match(/name\=\"form_build_id\" value=\"[^\"]+/gi);

        if (matches) {
            formTokenFields['form_build_id'] = matches[0].split('"').pop();
            formTokenFields['form_id'] = 'user_login';
            formTokenFields['op'] = 'Anmelden';
        }

        return formTokenFields;
    }

    /**
     * Posts login credentials to the backend.
     * @param credentials
     * @param formTokenFields
     * @returns {Observable<any>}
     */
    private postLoginForm(credentials, formTokenFields) {
        let url = 'user/login';
        let usernameField = 'name';
        let passwordField = 'pass';

        let postData = formTokenFields;
        postData[usernameField] = credentials.username;
        postData[passwordField] = credentials.password;

        let body = this.createSearchParams(postData);

        return this.post(url, body);
    }

    /**
     * Determines whether login was successful.
     * @param {string} html
     * @param html
     * @returns {boolean}
     */
    private checkLoginResponse(html) {
        // This is the tricky and hacky part. We must provide a test string
        // which will be included in the page after login.
        // A logout link is included normally only if a login is successful. 
        // So we can check the html for it.
        let loginSuccessText = 'href="/user/logout"';

        return html.includes(loginSuccessText);
    }

    /**
     * Creates a URLSearchParams with given params.
     * @param params
     * @returns {URLSearchParams}
     */
    private createSearchParams(params: any) {
        let searchParams = new URLSearchParams();
        for (let k in params) {
            if (params.hasOwnProperty(k)) {
                searchParams.set(k, params[k]);
            }
        }

        return searchParams;
    }
}

Thank you for sharing. Really appreciate it
You may already know this. Bu there is also this structured library which seems to be more comprehensive

Unfortunately all the demo programs are in ionic 1. But may be a starting point if someone attempts to port to ionic 3

Yes, I already saw this library but as you also see it is for ionic v1 and uses angularJS. Moreover, it requires Service module is installed on the Drupal backend.

My implementation does not require any special module to be installed on Drupal.

Hmm. I can see your solution does not require services for login. But How you plan to retrieve content without jason data? If I understand correctly services module takes care of exposing your endpoints as jason feeds. But if you don’t have that, wouldn’t you need something else in that place since Drupal 7 does not have API module in the core?

There are a lot of ways to produce JSON output from Drupal. Services module is one of those. I, personally, create my own endpoints in custom modules using drupal_json_output(). There is also Views Datasource module, which I used in an another project to produce JSON output.

@deggial - did you manage to find a way in implementing ionic with drupal login ?

@rameshrr99 I already posted my solution above. However, my post is one year old and it must be adjusted for Angular 5 and RxJS 5.5.