php - 如何使用 ArangoDB 在 PHP 中进行用户注册和身份验证?

标签 php database nosql arangodb arangodb-php

ArangoDB 是一个灵活的多模型数据库服务器,具有非常好的特性和大量好的文档。这是一个年轻的、非常有前途的开源项目,社区不断壮大,但没有多少现实世界的例子可以开始。

一个常见的真实示例是用户注册和身份验证。大多数应用程序都需要它。

那么,ArangoDB在PHP中如何进行用户注册和认证呢?

最佳答案

您可以直接运行以下示例代码,它将通过提供一些虚构的用户数据来运行用户注册和身份验证。
它将显示它正在执行的每个步骤。从收藏创建,到用户注册,身份验证,最后再次清理收藏。
还有很多注释解释正在做什么,以使其更容易理解。

只需将这段代码放在一个文件中,根据您的环境配置autoload.php 的路径,然后用浏览器访问它的链接。 此代码需要 ArangoDB 1.2 and up以及 ArangoDB-PHP client version 1.2及以上。
它期望 ArangoDB 在本地主机上运行并监听端口 8529。

注意 1:脚本会自动创建“用户”集合和“用户名”上的唯一跳过列表索引。它还会在最后丢弃该集合。
如果要手动创建集合而不是自动创建集合,则需要注释掉创建集合和索引的部分以及删除集合的部分。
之后打开 ArangoDB (arangosh) 的 shell 并在其中运行以下命令:

arangosh> db._createDocumentCollection('users');
arangosh> db.users.ensureUniqueSkiplist("username");

如果要删除集合,请键入:

arangosh> db.users.drop();


注意 2:为了保持简单,我有意避免引入更多 OO 风格,例如用户对象、地址对象等。

所以,最后是脚本。

<?php

namespace triagens\ArangoDb;


// use this and change it to the path to autoload.php of the arangodb-php client if you're using the client standalone...
// require __DIR__ . '/../vendor/triagens/ArangoDb/autoload.php';

// ...or use this and change it to the path to autoload.php in the vendor directory if you're using Composer/Packagist
require __DIR__ . '/../vendor/autoload.php';


// This function will provide us with our pre-configured connection options. 
function getConnectionOptions()
{
    $traceFunc = function ($type, $data) {
        print "TRACE FOR " . $type . PHP_EOL;
    };

    return array(
        ConnectionOptions::OPTION_ENDPOINT      => 'tcp://localhost:8529/',
        // endpoint to connect to
        ConnectionOptions::OPTION_CONNECTION    => 'Close',
        // can use either 'Close' (one-time connections) or 'Keep-Alive' (re-used connections)
        ConnectionOptions::OPTION_AUTH_TYPE     => 'Basic',
        // use basic authorization
        /*
        ConnectionOptions::OPTION_AUTH_USER       => '',                      // user for basic authorization
        ConnectionOptions::OPTION_AUTH_PASSWD     => '',                      // password for basic authorization
        ConnectionOptions::OPTION_PORT            => 8529,                    // port to connect to (deprecated, should use endpoint instead)
        ConnectionOptions::OPTION_HOST            => "localhost",             // host to connect to (deprecated, should use endpoint instead)
        */
        ConnectionOptions::OPTION_TIMEOUT       => 5,
        // timeout in seconds
        //ConnectionOptions::OPTION_TRACE           => $traceFunc,              // tracer function, can be used for debugging
        ConnectionOptions::OPTION_CREATE        => false,
        // do not create unknown collections automatically
        ConnectionOptions::OPTION_UPDATE_POLICY => UpdatePolicy::LAST,
        // last update wins
    );
}


// This function tries to persist the user data into the database upon registration
// it will fail if a user with the same username already exists.
function register($connection, $username, $password, $registrationData)
{
    // This would be where you call the function that encrypts your password like you did for storage earlier
    $hashedPassword = md5($password);

    // assign the collection to a var (or type it directly into the methods parameters)
    $collectionId = 'users';

    //create an example document or an array in order to pass to the following byExample method
    $document = Document::createFromArray(
        array('username' => $username, 'password' => $hashedPassword, 'data' => $registrationData)
    );

    // Get an instance of the collection handler
    $documentHandler = new DocumentHandler($connection);

    try {
        // query the given $collectionId by example using the previously declared $exampleDocument array
        $result = $documentHandler->add($collectionId, $document);

        // return the result;
        return $result;
    } catch (Exception $e) {

        if ($e->getCode()) {
            echo ('User already exists... ');
        } else {
            // any other error
            echo ('An error occured. Exception: ' . $e);
        }
    }
}


// This function tries to authenticate the user and will return an array with its data
function authenticate($connection, $username, $password)
{
    // This would be where you call the function that encrypts your password like you did for storage earlier
    $hashedPassword = md5($password);

    // assign the collection to a var (or type it directly into the methods parameters)
    $collectionId = 'users';

    //create an example document or an array in order to pass to the following byExample method
    $exampleDocumentArray = array('username' => $username, 'password' => $hashedPassword);

    // Get an instance of the collection handler
    $documentHandler = new CollectionHandler($connection);

    try {
        // query the given $collectionId by example using the previously declared $exampleDocument array
        $cursor = $documentHandler->byExample($collectionId, $exampleDocumentArray);
        // check if the count of the cursor is one or not.
        if ($cursor->getCount() == 1) {
            // do some fancy login stuff here...

            // get the current document from the cursor
            $userDocument = $cursor->current();

            // set session uid to the document key that was set automatically by ArangoDB,
            // since we didn't provide our own on registration
            $_SESSION['uid'] = $userDocument->getKey();

            // extract and return the document in form of an array
            return $userDocument->getAll();
        } else {
            return false;
        }
    } catch (Exception $e) {
        echo ('An error occured. Exception: ' . $e . '<br>');
    }
}


// register the connection to ArangoDB
$connection = new Connection(getConnectionOptions());


// register a collection handler to work with the 'users' collection
$collectionHandler = new CollectionHandler($connection);


// create the 'users' collection...
// remark those lines if you want to create the collection by hand.
echo "creating 'users' collection...";
try {
    $collection = new Collection();
    $collection->setName('users');
    $collectionHandler->create($collection);
    echo "created.<br>";
} catch (Exception $e) {
    echo ('Could not create collection. Exception: ' . $e . '<br>');
}


// create unique skip list index in 'users' collection on field ''username'...
// remark those lines if you want to create the index by hand.
echo "creating unique skip list index in 'users' collection on field ''username'... ";
try {
    $collection = new Collection();
    $collection->setName('users');
    $collectionHandler->index('users', 'skiplist', array('username'), true);
    echo "created.<br>";
} catch (Exception $e) {
    echo ('Could not create skip list index. Exception: ' . $e . '<br>');
}


// let's assume those variables hold your username / password
$userNameProvided = 'jane';
$passwordProvided = 'mysecretpassword';

// here we pass some structured registration data
$registrationData = array(
    'name'      => 'Jane',
    'surname'   => 'Doe',
    'addresses' => array(
        'email' => array('jane@doe.com', 'jane2@doe.com'),
        'home'  => array(
            array('street' => 'Brooklyn Ave.', 'number' => 10),
            array('street' => '54th Street', 'number' => 340, 'is_primary' => true)
        )
    )
);

// First register
echo "trying to register user for the first time... ";
$result = register($connection, $userNameProvided, $passwordProvided, $registrationData);
if ($result) {
    echo " " . $userNameProvided . " registered<br>";
} else {
    echo "failed<br>";
}


// Trying to register user with same username a second time
echo "trying to register user with same username a second time... ";
$result = register($connection, $userNameProvided, $passwordProvided, $registrationData);
if ($result) {
    echo "registered<br>";
} else {
    echo "failed<br>";
}


// now authenticate with the correct username/password combination
echo "trying to authenticate with the correct username/password combination... ";
if ($userArray = authenticate($connection, $userNameProvided, $passwordProvided)) {
    echo "login successful. ";
    echo '<br>';
    // do some fancy after-login stuff here...
    echo "<br>Welcome back " . $userArray['username'] . '!<br>';
    if (count($userArray['data']['addresses']['email']) > 0) {
        echo "Your primary mail address is " . $userArray['data']['addresses']['email'][0] . '<br>';
    }
    foreach ($userArray['data']['addresses']['home'] as $key => $value) {
        if (array_key_exists('is_primary', $value)) {
            $homeAddress = $userArray['data']['addresses']['home'][$key];
            echo "Your primary home address is " . $homeAddress['number'] . ', ' . $homeAddress['street'] . '<br>';
            // if found, break out of the loop. There can be only one... primary address!
            break;
        }
    }
} else {
    // re-display login form. +1 the wrong-login counter...
    echo "wrong username or password<br>";
}
echo '<br>';

// now authenticate with the wrong username/password combination
echo "trying to authenticate with the wrong username/password combination... ";
if (authenticate($connection, $userNameProvided, 'I am a wrong password')) {
    // do some fancy after-login stuff here...
    echo "login successful<br>";
} else {
    // re-display login form. +1 the wrong-login counter...
    echo "wrong username or password<br>";
}


// truncate the collection... not needed if dropping, but only here to empty the collection of its tests
// in case you decide to not create and drop the collection through this script, but by hand.
echo "truncating collection...";
try {
    $collectionHandler->truncate('users');
    echo "truncated.<br>";
} catch (Exception $e) {
    die ('Could not truncate collection. Exception: ' . $e . '<br>');
}


// finally drop the collection...
// remark those lines if you want to drop the collection by hand.
echo "dropping collection...";
try {
    $collectionHandler->drop('users');
    echo "dropped.<br>";
} catch (Exception $e) {
    die ('Could not drop collection. Exception: ' . $e . '<br>');
}

关于php - 如何使用 ArangoDB 在 PHP 中进行用户注册和身份验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15014957/

相关文章:

php - Magento/Zend Framework 中的内存泄漏

java - Android:从通知写入 Realm 数据库

database-design - NOSQL数据库设计

javascript - 处理 meteor 集合中可变的键值对(无模式困境)

ubuntu - 创建服务器 TCP 监听套接字 * :6379: bind: Address already in use

javascript - 使用 PHP - 是否可以在浏览器中设置 SessionStorage?

php - Wordpress/Woocommerce将帖子ID和订单ID偏移10000

php - jQuery 新手 - 为什么这个简单的函数不起作用?

database - 如何在 IF 语句中替换 SELECT 语句以使其工作

php - session 未插入数据库语法错误