Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
vp-webdev
6 лет назад

Пишем клиент для Голос в связке с CMS Joomla

Да, вы угадали, на связи @captain. У меня есть один проект, которому скоро исполнится уже год. Это альтернативный веб-клиент Голоса. Сначала я за него взялся с огоньком, но потом поостыл - ребенок родился, я несколько отошел от голоса. Вернулся к нему в начале осени, но потом переключился на торговую площадку https://golos.world и клиент как-то заглох. Сразу скажу, что это не убийца https://golos.io или GoldVoice. Это просто мое прочтение того, как должен выглядеть удобный мне сайт. Но нас интересует именно код, программные решения. Именно о них я и расскажу в серии своих статей. И надеюсь, что их кульминацией таки будет запуск клиента.

Разработка ведется на PHP, JS (и jQuery) и HTML(Bootstrap). Для каркаса сайта я использую Joomla, но это совершенно не обязательный элемент. К ней будет привязана только авторизация и система меню. Итогом будет не только веб клиент в сети Интернет, но и локальный клиент, который не будет зависеть от каких-либо серверов, а сможет запускаться с компьютера (хоть с флешки) локально.
До чего-то я дошел сам в процессе разработки, что-то подсмотрел у других, что-то выпытал в чатах.

Фигура первая. Подготовка и начало работы.

Нам нужно будет подключить к сайту библиотеку JS API Golos. Взять ее можно тут: https://github.com/GolosChain/golos-js
Также понадобится jQuery (да, я старомоден), хотя можно и без этого обойтись. Например, так:
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

И подключим Bootstrap 3

<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>

Еще раз повторюсь - можете подключать это к пустой html странице, можете к расширению для какого-то фреймворка или CMS, особой разницы нет. Итак, у нас все готово для начала работы.

Фигура вторая. Авторизация, хранение данных об авторизации, регистрация.

В данном случае у нас будет немного специфическое для Joomla решение. Но, в целом, это можно применить и для любой другой CMS, если вы умеете добавлять пользователей программно.

Делаем простую форму входа:

<form action="/index.php?option=com_greg&amp;task=save" method="post" id="adminForm" class="form-validate col-sm-10 col-sm-offset-1">
    <div class="form-group1">
    <label for="login" style="color: white;">Логин GOLOS<span style="color: red;">*</span> </label>
    <div class="input-group">
        <div class="input-group-addon">@</div>
        <input type="text" class="form-control required" id="login" name="login" onblur="checkLogin(this.value);" required="required"> 
        </div>
    </div>
    </div>        
    <div class="form-group1">
    <label for="key" style="color: white;">Постинг ключ</label> <span style="color: red;">*</span> 
    <input type="password" class="form-control required" id="key" name="key" placeholder="Начинается с 5" required="required">
    </div>
    <br>
    <div class="center" style="text-align: center;">
    <input type="hidden" name="ok" id="ok" value="false">
    <input type="button" class="btn btn-primary" value="Войти" onclick="if(!storeKeyLocally()){return false;};this.form.submit();">
    </div>
</form>

Посмотреть на pastebin

В эту форму пользователь должен ввести свой логин и приватный постинг ключ. Как видите, тут вызывается JS функция storeKeyLocally() перед отправкой формы. Она нужна для проверки ключа пользователя и сохранения его в localStorage браузера. А при вводе логина он проверяется функцией checkLogin(this.value);

Вот эти функции

function checkLogin(login)
{
    golos.api.getAccounts([login], function(err, response){
        if(response == '')
        {
            document.getElementById('login').value = '';
            return false;
        }
        return true;
    });
}

function storeKeyLocally()
{
    var login = document.getElementById("login").value;
    var key = document.getElementById("key").value;
    if(key && login)
    {
        localStorage.setItem(login, sjcl.encrypt(login, key));
        localStorage.setItem('login', login);
        return true;
    }       
    else
    {
        return false;
    }
}

Посмотреть на pastebin

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

<script src="https://cdnjs.cloudflare.com/ajax/libs/sjcl/1.0.7/sjcl.min.js" type="text/javascript"></script>

В этой функции мы сохраняем логин. А также мы сохраняем приватный ключ, зашифрованный логином пользователя.

После отправки формы она обрабатывается на сервере. Нам нужно будет занести пользователя в БД и сохранить хэш от его пароля. Это зависит конкретно от вашего фреймворка. Для Joomla это будет вот такой код в контроллере вашего компонента регистрации:

$app  = JFactory::getApplication();
$filter = JFilterInput::getInstance();
$username = $filter->clean( $app->input->getUsername('login', '') );
$password = $app->input->getVar('key');
$email = $username . '@golos.world'; // так как email у нас нет
$db = JFactory::getDBO();
$query = "select count(*) from `#__users` where email = '$email'";
$result = $db->setQuery($query);   
$n = $db->loadResult();
if($n > 0) // пользователь существует
{
    $credentials = array( 'username'=> $username, 'password'=> $password );
    //В этом массиве параметры авторизации! в данном случае это установка запоминания пользователя
    $options = array( 'remember'=>true );
    //выполняем авторизацию
    if( JFactory::getApplication()->login( $credentials, $options )){
        $url = JRoute::_( '/' );
        JControllerLegacy::setRedirect( $url, '');
        return true;
    }
    else
    {
        JError::raiseWarning('', 'Неверно указаны данные для входа');
        return false;                 
    }           
}

//добавляем пользователя
$data = array();
$data['name']       = $username;
$data['username']   = $username;
$data['email']      = $email;
$data['email1']     = $email;
$data['password']   = $password;
$data['password1']  = $password;
$data['password2']  = $password;
$data['password_clear'] = $password;
$data['sendEmail']  = 0;

$activation = $this->registerUser($data);

if($activation)
{
    $query = "update `#__users` set block = 0, activation = '' where email = '$email'";
    $result = $db->setQuery($query);   
    $result = $db->execute();

    $query = "select * from `#__users` where email = '$email'";
    $result = $db->setQuery($query);   
    $user = $db->loadObject();
    $credentials = array( 'username' => $username, 'password' => $password );
    $options = array( 'remember' => true );
    if( JFactory::getApplication()->login( $credentials, $options )){
        $url = JRoute::_( '/' );
        JControllerLegacy::setRedirect( $url, '');
        return true;
    }
}
else
{
    $message = 'Проблемы при входе...';
    JFactory::getApplication()->enqueueMessage($message, 'error');
    return false;
}

Посмотреть на pastebin

Для тех кто использует Joomla. Здесь использована функция registerUser, которая во многом повторяет соответствующую функцию компонента com_users, но из нее вырезана отправка активации пользователю и т.п.

Нужно отметить и еще один важный момент. На данном этапе, мы сознательно не используем login.api голоса. Все же доступ стороннего приложения к активному ключу это значительный риск. Это значит, что если пользователь сменил ключи, то для авторизации ему нужно будет обновить ключ. То есть, в клиенте нужно предусмотреть вход со старым постинг-ключом и замену его на новый.

Ну вот и все пока что, мы научились авторизовывать и регистрировать пользователя на нашем сайте. При этом мы не храним его постинг ключ, он хранится локально в браузере пользователя.


И немного пиара. @captain это делегат голоса. Вот его делегатский пост https://golos.io/@captain/post-delegata-captain/
@captain много чего делает для голоса и много чего еще сделает. Поэтому не поленитесь и проголосуйте за него тут https://golos.io/~witnesses или тут https://goldvoice.club/witnesses/

0
169.359 GOLOS
На Golos с August 2017
Комментарии (16)
Сортировать по:
Сначала старые