Ionic 6 implementing WordPress REST API

WordPress version 4.8 and later support REST API, we don’t need any plugin to create REST API. In this article and few articles, we will implementation following features:

  1. Authentication to WordPress site using JWT plugin.
  2. CRUD operation on post on WordPress site.
  3. Woo commerce implementation of our Ionic application.

To access the REST interface of a WordPress site use https://sitename/wp-json/wp/v2/ will give a JSON file containing all posts, custom post and page information.

Step 1: Create Front-end Ionic project.
ionic start wordpressApp –type=angular

Step 2: Install and setup WordPress JWT plugin on WordPress site.
To enable JWT authentication at Ionic front-end application, we need to install JWT Authentication for WP REST API plugin in our WordPress application. If your site is using HTTP and then you can install WordPress free plugin Really Simple SSL to enable HTTPS. We also need to configure our WordPress site to allow JWT authentication using REST API.

1. Enable HTTP authorization header :
Shared hosting by default disabled HTTP AUTHORIZATION HEADER. In WordPress site root folder have .htacces file and add following code at end of file.

RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

2. Configure secret key for JWT token
The JWT needs a secret key to sign the token this secret key must be unique and never revealed. To add the secret key edit your wp-config.php file and add a new constant called JWT_AUTH_SECRET_KEY and you can add any string of your choice.

define('JWT_AUTH_SECRET_KEY', 'secret-key');
define('JWT_AUTH_CORS_ENABLE', true);

When the JWT authentication plugin is activated, a new namespace is added to REST API
1. /wp-json/ jwt-auth/v1/token POST
2. /wp-json/ jwt-auth/v1/token /validate POST

The first is the entry point for the JWT Authentication. We need to pass username and password and it will validate the user credentials and returns a token to use in a future request to the API if the authentication is correct or error if the authentication fails. Success response from the server

{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1wMzEyLCJuYmYiOj6MTU4NDMzNTExMiwiZGF0YSI6eyJ1c2VyIjp7ImlkIjoiMSJ9fX0.-E2KmeY_MmNqgQWiARoYroT3MxmZkY_pQwoKwOegUl4",
    "user_email": "[email protected]",
    "user_nicename": "admin",
    "user_display_name": "admin"
}

Step 3: Implementing JWT Authentication at Ionic front end application.
We need to create login page, authentication service, auth guard and interceptor in our application to allow login.
$ ionic generate page pages/login
$ionic generate service services/auth

$ionic generate guard auth
Interceptors in Angular intercept and modify the application’s HTTP requests globally before they are sent to the server.  We will add our domain name to our HTTP request before they sent to the server. In environments/environment.ts file add our domain as

export const environment = {
  production: false,
  apiUrl: 'http://your-domainName.com/wp-json/',
  origin: 'http://your-domainName.com/wp-json/',
  wcEndpoint: 'wp/v2',
};

Create file http.interceptor.ts file in app root  add following code

import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor, HttpErrorResponse } from '@angular/common/http';

import { catchError } from 'rxjs/operators';
import { Observable, throwError } from 'rxjs';
import { environment } from '../environments/environment';

@Injectable()
export class AppInterceptor implements HttpInterceptor {

    constructor() { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
      let authRequest;

      let requestUrl = '';
    //   if (request.url.includes('api') || request.url.includes('jwt')) {
      if (request.url.includes('jwt')) {
        requestUrl = `${environment.origin}${request.url}`;
      } else {
        requestUrl = `${environment.origin}${environment.wcEndpoint}/${request.url}`;
      }
      authRequest = request.clone({
        url: requestUrl
      });

      return next.handle(authRequest)
        .pipe(
          catchError(err => {
            if (err instanceof HttpErrorResponse && err.status === 0) {
              console.log('Check Your Internet Connection And Try again Later');
            } else if (err instanceof HttpErrorResponse && err.status === 401) {
              // Todo refresh token
            }
            return throwError(err);
          })
        );
    }
}

The HttpClientModule will allow remote client to communicate with a remote server using HTTP request. We need to import HTTPClientModule in app. module. this file as

...
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AppInterceptor } from './http.interceptor';


@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [
    BrowserModule,
    IonicModule.forRoot(),
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AppInterceptor,
      multi: true
    },
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Implement auth.service.ts file and add following code

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Subject } from 'rxjs';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  user: any;
  isAuthenticated = false;
  token: string;
  authStatusListener = new Subject<boolean>();

  constructor(private http: HttpClient, private router: Router) { }

  getIsAuth() {
    return this.isAuthenticated;
  }

  getToken() {
    return this.token;
  }

  getAuthStatusListener() {
    return this.authStatusListener.asObservable();
  }

  onLogin(authData) {
    this.http.post('jwt-auth/v1/token', authData).subscribe(response => {
      const user: any = response;
      this.token = user.token;
      if (this.token) {
        localStorage.setItem('token', JSON.stringify(this.token));
        this.isAuthenticated = true;
        this.authStatusListener.next(true);
        this.router.navigate(['/posts']);
      }
    },
      error => {
        this.authStatusListener.next(false);
      }
    );
  }

  autoAuthUser() {
    this.token = JSON.parse(localStorage.getItem('token'));
    if (this.token) {
      this.isAuthenticated = true;
      this.authStatusListener.next(true);
    }
  }

  logout() {
    this.token = null;
    this.isAuthenticated = false;
    this.authStatusListener.next(false);
    this.clearAuthData();
    this.router.navigateByUrl('login');
  }

  private clearAuthData() {
    localStorage.removeItem('token');
  }
}

In app folder create folder called models and add user interface as user.ts

export interface IUser {
    token?: string;
    user_email: string;
    user_nicename: string;
    user_display_name: string;
}

Implement login form:-
On login page, we have a simple form with two fields: the username and the password. When the user clicks the submit button, the username and password are then sent to auth.service onLogin method which will send our request to the remote WordPress server. On successful authentication will return a JSON object containing user information and token. We will save user token in local storage for future HTTP requests. In login.page.html add the following code

<ion-header>
  <ion-toolbar>
    <ion-title size="small">Login to Excel PDF Converter</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <div class="spin" *ngIf="isLoading">
    <ion-spinner name="bubbles"></ion-spinner>
  </div>
  <ion-grid>
    <ion-row>
      <ion-col size-sm="8" offset-md="2">
        <ion-card>
          <form [formGroup]="form">
            <ion-item>
              <ion-label position="floating">Username</ion-label>
              <ion-input formControlName="username"></ion-input>
            </ion-item>
            <ion-item>
              <ion-label position="floating">Password</ion-label>
              <ion-input type="password" formControlName="password"></ion-input>
            </ion-item>
          </form>
        </ion-card>
      </ion-col>
    </ion-row>
  </ion-grid>

</ion-content>

In login.page.ts component implement following code

import { Component, OnDestroy } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { AuthService } from '../auth.service';

@Component({
  selector: 'app-login',
  templateUrl: './login.page.html',
  styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnDestroy {
  form: FormGroup;
  isLoading = false;

  constructor(
    private fb: FormBuilder,
    private auth: AuthService,
  ) {
    this.createForm();
  }

  createForm() {
    this.form = this.fb.group({
      username: ['', Validators.required],
      password: ['', Validators.required],
    });
  }

  submit() {
    this.auth.onLogin(this.form.value);
    this.isLoading = true;
  }

  ngOnDestroy() {
    this.form.reset();
  }
}


In app.component page, we will implement logout functionality, clicking logout button will remove both user and token information in local storage and also when an authenticated user to refresh or reload the site we need to retrieve token from local storage.

import { Component } from '@angular/core';
import { Platform } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { AuthService } from './auth/auth.service';

@Component({
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.scss']
})
export class AppComponent {
  constructor(
    private platform: Platform,
    private splashScreen: SplashScreen,
    private statusBar: StatusBar,
    private auth: AuthService
  ) {
    this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();
      this.auth.autoAuthUser();
    });
  }
}
Spread the love

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top