移动应用开发 - 如何创建服务器实现

6

编辑:起初,我认为Oauth2是一个不错的选择,但现在可能并不是。由于这会让问题更加混乱,所以我暂且不提这个问题。

我正在开发一个移动应用程序(Android/iOS)。我希望用户在移动设备上输入他们的凭据(用户名/密码),然后将它们发送到我的服务器(Joomla CMS)以验证凭据并创建/发送令牌。我不想在设备上存储用户名/密码,只想存储令牌。

此外,这个令牌需要一个超时时间,在需要时进行刷新。比如凭据已经改变。

目前,我正在试图弄清楚这个架构会是什么样子。

是否有任何教程可以告诉你如何实现这一点(最好是与Joomla一起)?有人能指导我吗?

5个回答

3
最终的解决方案是创建自己的Joomla组件。几乎所有的内容都在我的控制器中。以下不是最终代码,但类似于此的代码将会起作用。
defined('_JEXEC') or die;
jimport('joomla.application.component.controller');

class FooauthController extends JController
{
function __construct() {
    // params
    $jinput = JFactory::getApplication()->input;
    $this->username = $jinput->get('user', '', 'STRING');
    $this->password = $jinput->get('password', '', 'STRING');
    $this->checkParameters();
}

private function checkParameters() {
    // datatype checks

    if ($this->username == '' || $this->password == '') {
        header('HTTP/1.1 400 Bad Request', true, 400);
    }

}

private function createToken() {
    // token generation - what Joomla does (just an example)
    jimport('joomla.user.helper');
    $salt   = JUserHelper::genRandomPassword(32);
    $crypted  = JUserHelper::getCryptedPassword($password, $salt);
    $cpassword = $crypted.':'.$salt;
    return $cpassword;
}

function execute() {
    // Get the global JAuthentication object
    jimport( 'joomla.user.authentication');
    $auth = & JAuthentication::getInstance();
    $credentials = array( 'username' => $this->username, 'password' => $this->password );
    $options = array();
    $response = $auth->authenticate($credentials, $options);

    // success
    if ($response->status === JAUTHENTICATE_STATUS_SUCCESS) {
        $response->status = true;
        echo json_encode($this->createToken());
    } else {
        // failed
        $response->status = false;
        echo json_encode($response);
    }

}

这表示一个组件,称为com_fooauth。现在原生应用程序将发送此查询:

这代表了一个名为com_fooauth的组件。现在本地应用将发送如下查询:

http://www.myhost.com/index.php?option=com_fooauth&user=username&password=pass&format=raw

这种将所有内容放在控制器中的方法有点像捷径,但希望您能理解。


3

1
我希望我正确理解了您的用例。
如果您想使用oAuth,那么您的移动应用程序将被视为oAuth客户端。您的“服务器”持有“受保护资源”,只能使用oAuth访问令牌才能使用,因此它被称为“资源服务器”。现在您需要一些东西来提供此访问令牌,因此这是身份提供者,也称为认证服务器,例如Facebook、Google(或自行实现)。
流程通常如下:用户(移动应用程序)尝试访问受保护的资源;由于它没有令牌,他被重定向到auth-server。后者负责用户/密码登录页面,并创建令牌。
如果是真的 - 您仍然可以自己实现所有内容,而不使用Facebook / Google API,因为oAuth具有规范。但是,对您来说使用提供者的包可能更容易。
编辑:重新考虑使用oAuth
你只有在想让你的网络应用支持oAuth SPEC时才会使用oAuth。它有几个好处,其中之一是你可以使用第三方身份提供者,例如Yahoo!,并使用他们的身份而无需管理它们。因此,如果我在Yahoo!中有一个用户,我可以在不进行额外注册的情况下使用你的应用程序(你的应用程序将需要支持来自Yahoo!的访问令牌!)。但在你的情况下,你将要实现所有身份提供者的逻辑(忘记密码、更改密码、注册等),并支持oAuth——所有这些都没有享受到oAuth的好处!因此,你必须重新考虑使用oAuth的方式...

我不确定我理解你的意思。我相信“资源服务器”和“授权服务器”将是相同的(在我的情况下是Joomla)。我不明白为什么我要使用Facebook或Google API,因为我不打算让用户使用FB或Google登录他们的移动应用程序?他们需要使用Joomla进行身份验证,所以我不得不构建自己的实现吗? - Tom
通常在oAuth中,授权服务器和资源服务器不是同一个应用程序。以谷歌为例:您有Google帐户(oAuth服务器),而Calendar或GMail是“资源服务器”应用程序,并使用Google帐户作为身份提供者。在您的情况下,如果您愿意,它们可以合并在一起-我知道有些情况它们被视为一个应用程序。您想将Joomla用作认证服务器吗?Joomla是否充当认证服务器?(我不知道)。或者您想要使用Joomla开发的应用程序作为认证提供者?区别很重要... - OhadR
Joomla是一种具有自己身份验证的CMS。因此,我在Joomla中构建了一个站点,用户可以登录到我们的站点,并且受保护的资源位于其中(因此是“资源服务器”)。向客户端发出令牌的服务器也将是Joomla内部的组件(或插件)(因此是“授权服务器”)。因此它们是相同的。为什么这种区别很重要呢? - Tom
区别很重要,因为我提到了两种完全不同的用例。所以如果我理解您的用例,您将拥有一个同时作为资源服务器和身份验证服务器的 Web 应用程序。问题是 - 为什么您要支持oAuth?这似乎不是必须的(除非您想通过设计支持oAuth)。为什么不考虑使用常规的用户名/密码保护的 Web 应用程序(没有oAuth)呢? - OhadR
这不是必须的。你提出了一个很好的问题。我假设Oauth2是原生应用程序与我的Joomla数据库通信的正确方向。也许并不是,因此这篇文章缺乏答案。 - Tom
显示剩余2条评论

0

这不是Joomla或教程,(而且我在php方面非常生疏)话虽如此...

首先有几个注意事项: * memcache不安全,这个实现让你放置用户名/密码:确保它安全地位于防火墙后面,或者先加密。如果需要,我很乐意给出一些指针。 * 如果内存不足,memcache不能保证不会丢失数据。实际上它是可靠的,但你的应用程序应该优雅地处理它。如果你不想丢失那样的数据,只需将类似couchbase的东西替换为memcache。 * 只返回一个令牌作为登录响应可能并不是非常有用。我会将令牌与用户名、任何其他信息一起进行json化,以便在不需要进行第二个API调用的情况下启动应用程序。 * 下面的代码不处理错误情况,如果你没有意识到这一点,我可以详细说明所有错误情况。

如果是我,我会使用memcache来持久化令牌,并将该令牌映射到最初传递的用户名和密码。你可以使用memcache的生存时间免费获得过期时间。

将用户名/密码发送到服务器(最好通过https)。 创建一个随机字符串或GUID(例如:http://php.net/manual/en/function.uniqid.phphttp://www.lateralcode.com/creating-a-random-string-with-php/),这是您的令牌。 使用该令牌作为键将用户名/密码存储在memcache中。 设置超时。

$token = createToken("user1234", "pass2324");

print "Token: $token \n\n";

$credentials = credtialsFromToken($token);

print "Credentials from the token: ";

var_dump($credentials);

print "\n\n";


function setup() {
    $memcache = new Memcache;
    $memcache->connect('localhost', 11211) or die ("Could not connect");    
}

function createToken($user, $pass) {
$TOKEN_EXPIRE_TIME=60 * 60 * 24 * 30;

$credentials = array(
      "user" => $user,
      "pass" => $pass,
);

$token = uniqid(  );
memcache_set($token, credentials, 'some variable', 0, 30);

return $token;
}

function credtialsFromToken($token) {
$credentials = memcache_get($token);
return $credentials;
}

如果令牌不正确或已过期,则会返回空凭据并需要重新登录。
编辑:将其清理为在PHP中运行的函数...

0
你需要以他们的API为基础。他们不会让你建立自己的API连接到他们的数据库,否则对他们来说看起来更像是密码破解器而不是API。

你误解了问题。我不想连接到他们的数据库。我不想与Google、FB等有任何关系。我想构建一个本地应用程序,它将与我的数据库通信。 - Tom
抱歉我误解了你的问题。我现在正在上课,但我会再思考一下这个问题。 - Charles D Pantoga

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接