Back to all posts

User Login With WordPress using React Native


In this blog post, we’ll walk you through how to build a secure login and post creation system in WordPress using a custom plugin. This system is designed specifically for React Native mobile apps, but it can also be used with any client that can interact with a REST API.

🏘️ Plugin Setup

1. Create Plugin Directory and File

Create the following folder inside your wp-content/plugins/ directory:

wp-mobile-login/
└── wp-mobile-login.php

2. Plugin Header and Login Endpoint

Paste the following code into wp-mobile-login.php:

<?php
/*
Plugin Name: WP Mobile Login API
Description: Provides a REST API endpoint for mobile app login using email and password.
Version: 0.1
Author: Chethan S Poojary
*/

if (!defined('ABSPATH')) {
    exit; // Prevent direct access
}

add_action('rest_api_init', function () {
    register_rest_route('mobile/v1', '/login', [
        'methods' => 'POST',
        'callback' => 'wp_mobile_login_handler',
        'permission_callback' => '__return_true',
    ]);
});

function wp_mobile_login_handler(WP_REST_Request $request) {
    $email = sanitize_text_field($request->get_param('email'));
    $password = $request->get_param('password');

    $response = [
        'data' => [],
        'msg' => 'Invalid email or password',
        'status' => false,
    ];

    if (!$email || !$password) {
        $response['msg'] = 'Email and password are required';
        return new WP_REST_Response($response, 400);
    }

    $user = get_user_by('email', $email);

    if ($user && wp_check_password($password, $user->user_pass, $user->ID)) {
        $token = bin2hex(random_bytes(16));
        update_user_meta($user->ID, 'auth_token', $token);

        $response['status'] = true;
        $response['msg'] = 'Successfully Authenticated';
        $response['data'] = [
            'auth_token' => $token,
            'user_id' => $user->ID,
            'user_login' => $user->user_login,
        ];

        return new WP_REST_Response($response, 200);
    }

    return new WP_REST_Response($response, 403);
}

🚀 How to Use From React Native or Postman

Login:

POST https://yourdomain.com/wp-json/mobile/v1/login

Body (JSON):

{
  "email": "user@example.com",
  "password": "securepassword"
}

React Native Approch:


import React, { useState } from 'react';
import {
  View,
  Text,
  TextInput,
  TouchableOpacity,
  ActivityIndicator,
  StyleSheet,
  Alert
} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { router } from 'expo-router';

interface LoginResponseData {
  auth_token: string;
  user_id: string | number;
  user_login: string;
}

export default function Profile() {
  const [email, setEmail] = useState<string>('');
  const [password, setPassword] = useState<string>('');
  const [validating, setValidating] = useState<boolean>(false);

  const validate = async () => {
    setValidating(true);
    const formData = new FormData();
    formData.append('type', 'login');
    formData.append('email', email);
    formData.append('password', password);

    try {
      const response = await fetch('http://blogchethanspoojarycom.local/wp-json/mobile/v1/login', {
        method: 'POST',
        body: formData,
      });
      const responseJson = await response.json();

      if (responseJson.status) {
        await saveToStorage(responseJson.data);
        setValidating(false);
        console.log('Login sucessfull:', responseJson)
        router.replace('/(tabs)'); // Adjust this route to your needs
      } else {
        setValidating(false); 
        Alert.alert(
          'Login Failed',
          responseJson.msg || 'Incorrect email or password'
        );
      }
    } catch (error) {
      setValidating(false);
      Alert.alert('Error', 'An error occurred. Please try again.');
      console.error(error);
    }
  };

  const saveToStorage = async (userData: LoginResponseData) => {
    if (userData) {
      await AsyncStorage.setItem(
        'user',
        JSON.stringify({
          isLoggedIn: true,
          authToken: userData.auth_token,
          id: userData.user_id,
          name: userData.user_login,
        })
      );
      return true;
    }
    return false;
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>WordPress Login</Text>
      <TextInput
        value={email}
        onChangeText={setEmail}
        placeholder="Email"
        autoCapitalize="none"
        style={styles.input}
        keyboardType="email-address"
      />
      <TextInput
        value={password}
        onChangeText={setPassword}
        placeholder="Password"
        autoCapitalize="none"
        secureTextEntry
        style={styles.input}
      />
      <TouchableOpacity style={styles.button} onPress={validate} disabled={validating}>
        {validating ? (
          <ActivityIndicator color="#fff" />
        ) : (
          <Text style={styles.buttonText}>Login</Text>
        )}
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 24,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#fff',
  },
  title: {
    fontSize: 22,
    marginBottom: 24,
    fontWeight: 'bold',
  },
  input: {
    width: '100%',
    borderWidth: 1,
    borderColor: '#dcdcdc',
    borderRadius: 4,
    padding: 12,
    fontSize: 16,
    marginBottom: 16,
  },
  button: {
    backgroundColor: '#007aff',
    padding: 14,
    borderRadius: 4,
    minWidth: '100%',
    alignItems: 'center',
  },
  buttonText: {
    color: '#fff',
    fontWeight: 'bold',
  },
});