N
N
Nikita2022-04-13 11:50:46
OAuth
Nikita, 2022-04-13 11:50:46

How do I set up authentication for a Wordpress site and a third party application?

There is an application, the application key and id are known. I have a WordPress site (multisite).
How to link them together knowing the above data? By the word "link", I mean that when registering or entering the application, the site shared data with the client (application), that is, in fact, when registering in the application, you register on the site.
I know that Oauth and REST API technologies are used, there is even a code example (it is below), but I'm not special, I don't know how to use it, where to insert this code, what to change in it. Please tell me who has experience with the integration of WP sites and applications, at least direct them to the right track so that you can figure it out.

<?php
/** /
error_reporting( E_ALL );
ini_set( 'display_errors', 1 );
ini_set('display_startup_errors', 1);
/**/

session_start();

//	Пример OAuth2 класса для получения и обновления токена для доступа к API на PHP
class ClientOAuth2{
  public $clientId     = ''; // id приложения
  public $clientSecret = ''; // Ключ приложения
  public $redirectUri  = ''; // Адрес, на который будет переадресован пользователь после прохождения авторизации
  
  public $baseUrl     = 'https://app.cmmnt.net/api/'; // заменить на https://app.cmmnt.net/api/
  public $access_token     = false;
  
  function __construct( $clientId, $clientSecret, $redirectUri ){
    
    $this->clientId = $clientId;
    $this->clientSecret = $clientSecret;
    $this->redirectUri = $redirectUri;
    
    $this->access_token = $this->getSessionToken();
    if ( $this->access_token === false ){
      $this->init();
    }
    elseif ( $_SESSION['token']['expiresIn'] < time() ){
      // получаем актуальный токен с использованием refresh_token
      $this->refreshToken();
    }
  }
  
  public function sendRequest($action = '', $method = 'GET', $query = array()){
    $query = http_build_query( $query );
    //$query = json_encode($query, JSON_UNESCAPED_UNICODE);

    // Формирование заголовков запроса
    $header = "Content-type: application/x-www-form-urlencoded"
      .(( $this->access_token !== false ) 
        ? "\r\nAuthorization: {$_SESSION['token']['tokenType']} {$this->access_token}"
        : '')
      
    ;

    // Выполнение запроса
    $opts    = array(
      'http' =>
        array(
          'method'  => $method,
          'header'  => $header,
          'content' => $query,
        ),
      /**/
      'ssl' => array( // FOR TEST
        'allow_self_signed' => true,
        'verify_peer' => false,
        'verify_peer_name' => false,
      ),
      /**/
    );
    $context = stream_context_create( $opts );

    if ( !$content = @file_get_contents( $this->baseUrl . $action, false, $context ) ) {
      $error = error_get_last();
      throw new Exception( 'HTTP request failed. Error: ' . $error['message'] );
    }
    
    return json_decode( $content, true );
  }
  
  public function tokenToSession($response){
    // Сохраняем токен в сессии
    $_SESSION['token'] = array(
      'access_token' => $response['access_token'], // OAuth-токен с запрошенными правами или с правами, указанными при регистрации приложения.,
      'refresh_token' => $response['refresh_token'], // Токен, который можно использовать для продления срока жизни соответствующего OAuth-токена.
      'tokenType' => $response['token_type'], // Тип токена //Bearer
      'expiresIn' => time() + $response['expires_in'], // Время жизни токена в секундах.
    );
  }
  
  public function getSessionToken(){
    return (isset($_SESSION['token']) && isset($_SESSION['token']['access_token']) ) 
      ? $_SESSION['token']['access_token']
      : false;
  }
  
  public function refreshToken(){
    // получаем актуальный токен с использованием refresh_token
    $response = $this->sendRequest('access_token', 'POST', array(
      'grant_type'    => 'refresh_token',
      'refresh_token' => $_SESSION['token']['refresh_token'],
      'client_id'     => $this->clientId,
      'client_secret' => $this->clientSecret,
    ));
    // Если при получении токена произошла ошибка
    if ( isset( $response->error ) ) {
      throw new Exception( 'При получении токена произошла ошибка. Error: ' . $response->error . '. Error description: ' . $response->error_description );
    }
    else{
      // Сохраняем токен в сессии
      $this->tokenToSession($response);
    }
  }
  
  public function init(){
    if ( isset($_GET['code']) ){
      // отправляем POST-запрос с указанием кода подтверждения
      $response = $this->sendRequest('access_token', 'POST', array(
        'grant_type'    => 'authorization_code',
        'code'          => $_GET['code'],
        'client_id'     => $this->clientId,
        'client_secret' => $this->clientSecret,
        
        'redirect_uri'  => $this->redirectUri,
      ));
      // Если при получении токена произошла ошибка
      if ( isset( $response->error ) ) {
        throw new Exception( 'При получении токена произошла ошибка. Error: ' . $response->error . '. Error description: ' . $response->error_description );
      }
      else{
        // Сохраняем токен в сессии
        $this->tokenToSession($response);
        $this->access_token = $this->getSessionToken();
        
        if ( isset($_SESSION['redirectToUrl']) ){
          $url = $_SESSION['redirectToUrl'];
          unset( $_SESSION['redirectToUrl'] );
          header("Location: {$url}");
        }
      }
    }
    elseif ( isset( $_GET['error'] ) ) {
      // Если при авторизации произошла ошибка
      throw new Exception( 'При авторизации произошла ошибка. Error: ' . $_GET['error'] . '. Error description: ' . $_GET['error_description'] );
    }
    else{
      $_SESSION['redirectToUrl'] = $_SERVER['REQUEST_URI'];
      // переходим на сервер авторизации
      $url = $this->baseUrl . 'authorize?' . http_build_query(array(
        'client_id'     => $this->clientId,
        'redirect_uri'  => $this->redirectUri,
        'response_type' => 'code',

        // Список необходимых приложению в данный момент прав доступа, разделенных пробелом.
        // Права должны запрашиваться из перечня, определенного при регистрации приложения.
        // Если параметр scope не передан, то токен будет выдан с правами, указанными при регистрации приложения.
        // Параметр позволяет получить токен только с теми правами, которые нужны приложению в данный момент.
        'scope'         => 'profile',
      ));
      header("Location: {$url}");
    }
  }
  
}

/*
  id приложения, 
  Ключ приложения, 
  Адрес, на который будет переадресован пользователь после прохождения авторизации
*/
$auth = new ClientOAuth2( '128', '3DABBD811363D0CA894E0C92C0C8D096', 'https://zaskolkovo.ru/test.php');




if ( $auth->access_token ){
  echo 'авторизован<br/>';
  
  // запрос на получение данных пользователя
  $response = $auth->sendRequest('me', 'GET');
  
  echo "Ник: {$response[0]['nickname']}<br/>";
  echo "Имя: {$response[0]['given']}<br/>";

}
else{
  echo 'не авторизован<br/>';
}

?>

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question