Headless WordPress: реализуем вход в приложение под своим логином с помощью JWT

Headless WordPress: реализуем вход в приложение под своим логином с помощью JWT
Click here to view original web page at oddstyle.ru

Автор:

Дата публикации:

Headless WordPress – идея, которая используется все активнее в среде разработчиков. Я постараюсь раскрыть несколько тем, связанных с этим подходом. В частности, я покажу, как реализовать вход в приложение с помощью JWT.

Мы создадим простое приложение, которое позволит пользователям входить под своим логином. После входа мы выведем пользователю его данные.

Чтобы реализовать вход в приложение с помощью JWT, нам понадобится установить и активировать плагин JWT Authentication for WP REST API.

Подготовка приложения

Давайте создадим наше собственное приложение React с помощью Create React App. Открываем терминал (командную строку) и переходим к каталогу, в которой будет вестись разработка приложения.

Затем используем команду:

01npx create-react-app my-app

Здесь вы можете заменить my-app на свое название. Это будет ваш каталог, в котором будет храниться весь код. Я решил назвать каталог headless.

Затем перейдите к этой папке. Запустить приложение можно уже сейчас с помощью команды npm start. Однако давайте сначала установим Gutenberg Components, npm-пакет @wordpress/components. Это позволит нам использовать различные компоненты в своем приложении.

Установить Gutenberg Components можно с помощью команды

01npm install @wordpress/components

Поскольку пакет Gutenberg Components не включает в себя классы разметки, мы можем создать свое собственное руководство по CSS-стилям либо использовать существующие стилевые фреймворки, чтобы не тратить на это свое время. Если вы хотите создать приложение, которое будет использоваться в производстве – обязательно подумайте над тем, чтобы создать свою CSS-разметку.

Мы будем использовать Bootstrap 4 для стилей. Установить его можно с помощью команды:

01npm install bootstrap

Также нам потребуется процессинг SASS (SCSS), потому нам нужно, чтобы наше приложение могло обрабатывать такие файлы. Для этого используется следующая команда:

01npm install node-sass --save

Поскольку мы будем использовать стили Bootstrap и Gutenberg, мы можем удалить App.css и создать App.scss. Поместите следующее внутрь этого нового файла:

01@import '~bootstrap/scss/bootstrap.scss';
03@import '~@wordpress/components/build-style/style.css';

Теперь он будет компилироваться в файл CSS, который будет включать в себя стили как Boostrap, так и Gutenberg.

Нам нужно будет выполнять запросы POST и GET к нашему сайту WordPress, потому нам понадобится способ реализации этого. Вы можете использовать fetch из API браузера, либо библиотеку. Мы будем использовать библиотеку axios. Она устанавливается с помощью команды

01npm install axios

Добавляем логику входа к нашему Headless WordPress

Откройте App.js, чтобы начать добавление логики входа. Мы будем проверять, является ли пользователь залогиненным или нет. Если нет, то мы покажем форму входа. В противном случае будет выводиться консоль.

Давайте скорректируем все импорты в приложении:

01import React, { useState, useEffect } from 'react';
02import './App.scss';
03import '@wordpress/components/build-style/style.css';
04import Login from './components/Login';
05import Dashboard from './components/Dashboard';

Не беспокойтесь по поводу появляющихся ошибок. Компоненты Dashboard и Login пока что не существуют, потому вы можете получать ошибки компиляции.

Теперь мы можем заменить функцию App на следующее:

01function App() {
02const [login, setLogin] = useState( '' );
03const siteURL = 'yoursite_here';
05useEffect(() => {
06const localLogin = localStorage.getItem('login');
07// If we have logged in, set it.
08if ( localLogin ) {
09setLogin( localLogin );
11}, [login]);
13return (
15<div className="App container">
17<h1>Headless WordPress</h1>

Что мы здесь сделали:

  • Мы использовали хуки React useState для глобальной обработки информации по логину
  • Мы использовали хуки useEffect для обработки изменений в процессе входа в приложение
  • Если мы залогинены, то в таком случае будет выведен компонент Dashboard
  • Если мы не вошли в приложение, то тогда будет выведен компонент Login

С помощью useEffect наше приложение будет осуществлять вход нашего пользователя (если токен сохранен).

Мы передаем в оба компонента функцию setLogin, которая управляет глобальным состоянием для информации по входу в систему. Это позволит нам, к примеру, предлагать логаут для пользователей.

Создание компонента Login

Чтобы осуществить процедуру входа в наше приложение Headless WordPress для пользователя, нам нужно передать логин и пароль с первой попытки. Для этого нам нужна отдельная форма. Создадим папку components в папке с приложением и создадим файл Login.js.

Поместим в него следующий код:

01import React from 'react';
02import { TextControl, Button } from '@wordpress/components';
04const axios = require('axios');
06class Login extends React.Component {
07constructor( props ) {
08super( props );
09this.state = { username: '', password: '' }
10this.handleUsername = this.handleUsername.bind(this);
11this.handlePassword = this.handlePassword.bind(this);
12this.handleSubmit = this.handleSubmit.bind(this);
16export default Login;

Мы импортируем Gutenberg-компоненты TextControl и Button, которые мы будем использовать для создания формы входа. У нас также будет еще 3 метода. Эти методы будут использоваться для хранения информации о состоянии входа в приложение, а также о логине пользователя.

Давайте создадим метод render и 2 метода для сохранения информации о состоянии входа. Вы увидите, как мы используем Gutenberg Components.

03class Login extends React.Component {
06handleUsername( username ) {
07this.setState( { username } )
10handlePassword( password ) {
11this.setState( { password } )
13render() {
14return (
16<form className="login" method="post">
17<TextControl className="form-group" label="Username" value={ this.state.username } onChange={ (value) => this.handleUsername( value ) }
19<TextControl className="form-group" label="Password" type="password" onChange={ (value) => this.handlePassword( value ) }

Второй TextControl также получает password в качестве типа. Когда какой-либо из элементов управления изменится, он будет использовать соответствующий метод для сохранения информации о состоянии входа.

При нажатии на компонент Button мы будем пытаться войти в систему под пользователем. Давайте создадим этот метод сейчас:

03class Login extends React.Component {
04//...
06handleSubmit( e ) {
07e.preventDefault();
08const _this = this;
09axios.post( this.props.url + '/wp-json/jwt-auth/v1/token/',
11username: this.state.username,
12password: this.state.password
14.then(function (response) {
15if ( response.status === 200 ) {
16const data = response.data;
17localStorage.setItem( 'login', data.token );
18_this.props.setLogin( data.token );
21.catch(function (error) {
22function strip_html_tags(str) {
23if ((str===null) || (str===''))
24return false;
25else
26str = str.toString();
27return str.replace(/<[^>]*>/g, '');
29alert( strip_html_tags( error.response.data.message ) );
33// ...

Мы публикуем имя пользователя и пароль в REST-маршруте для токена jwt. Если пользователь существует, то нам будет возвращен этот токен. Затем мы внесем токен в локальное хранилище, чтобы мы могли получить его при обновлении.

Если этот REST-маршрут вернет нам какие-либо ошибки, мы отобразим их без HTML-тегов.

Все это позволит нашим пользователям войти в приложение WordPress Headless.

Создание компонента Dashboard

В нашем компоненте Dashboard мы будем выводить информацию о нашем пользователе, чтобы мы знали, что мы получили корректного пользователя.

Создаем файл Dashboard.js внутри каталога components и помещаем в него следующее:

01import React from 'react';
02const axios = require('axios');
04class Dashboard extends React.Component {
05constructor( props ) {
06super( props );
07this.state = { user: { } };
08this.Logout = this.Logout.bind(this);
09this.getCurrentUser = this.getCurrentUser.bind(this);
13export default Dashboard;

Нам также понадобится здесь axios, поскольку мы будем получать информацию о текущем залогиненном пользователе. Мы хотим получить эту информацию как можно скорее, еще когда компонент монтируется.

02class Dashboard extends React.Component {
03// ...
05componentDidMount() {
06this.getCurrentUser();
09getCurrentUser() {
10const token = this.props.token;
11const userURI = this.props.url + '/wp-json/wp/v2/users/me';
12const _this = this;
14method: 'POST',
15url: userURI,
16headers: { 'Authorization': 'Bearer ' + token }
17}).then(function (response) {
18if ( response.status === 200 ) {
19const data = response.data;
20_this.setState( {user:data});
24.catch(function (error) {
25_this.Logout();

Мы используем маршрут wp-json/wp/v2/users/me для получения информации о текущем пользователе. Для этого мы передаем заголовок Authorization с нашим Bearer токеном.

Если мы не передадим этот заголовок, то плагин JWT не сможет определить, какой пользователь вошел в приложение.

Давайте теперь выведем информацию о залогиненном пользователе:

03class Dashboard extends React.Component {
04// ...
06Logout() {
07localStorage.removeItem('login');
08this.props.setLogin('');
11render() {
12const { nickname, first_name, last_name } = this.state.user;
13return (
15<div className="dashboard">
16<button type="button" className="btn btn-danger" onClick={this.Logout}>Logout</button>
19<div className="jumbotron">
20Welcome { nickname }
23I think your name is { first_name } { last_name}

У нас есть кнопка логаута, которая также будет использовать переданный метод setLogin. Поскольку мы задали логин в виде пустой строки, приложение выполнит повторный рендеринг и выведет форму входа.

Заключение

Headless WordPress постепенно становится новым стандартом. Вы можете создать такое веб-приложение, которое легко можно будет впоследствии преобразовать в Android или iOS-приложение. Пакет Gutenberg Components значительно экономит время и силы.

Источник: https://www.ibenic.com