mobile app development - how to create a server implementation
Asked Answered
A

5

6

EDIT Originally I thought Oauth2 is the way to go but maybe it is not. I'll leave that out of this question for now as it is confusing things.

I'm creating a mobile app (Android/iOS). I'd like the user to enter their credentials (user/pass) in the mobile device which would then get sent to my server (Joomla CMS) to verify the credentials and create/send a token. I don't want to store the user/pass on the device just the token.

In addition this token needs to have a timeout to be refreshed when needed. Such as credentials have changed.

At this point I'm trying to figure out what the architecture of this will look like.

Are there any tutorials on how you can achieve this (ideally with Joomla)? Anything that someone could point me to?

Arcadia answered 24/1, 2013 at 15:59 Comment(0)
A
3

The end solution is to create my own Joomla component. Pretty much everything is in my controller. Not the final code but something like this will work.

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);
    }

}

}

This represents a component called com_fooauth. Now the native app will send a query like this:

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

Kind of a short cut to put everything in the controller, but hopefully you get the idea.

Arcadia answered 30/1, 2013 at 18:43 Comment(0)
C
3

You should post the username and password from the mobile app and from there on you should follow the solution provided in this question: https://mcmap.net/q/1776891/-joomla-login-authentication-from-external-app

Confluence answered 30/1, 2013 at 15:24 Comment(0)
A
3

The end solution is to create my own Joomla component. Pretty much everything is in my controller. Not the final code but something like this will work.

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);
    }

}

}

This represents a component called com_fooauth. Now the native app will send a query like this:

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

Kind of a short cut to put everything in the controller, but hopefully you get the idea.

Arcadia answered 30/1, 2013 at 18:43 Comment(0)
I
1

I hope that I understand correctly your use case.

If you want to use oAuth, then your mobile apps are considered as the oAuth-client. Your "server" holds the "protected resources", and it can be used only with oAuth access-token, so it is called "resource server". Now you want something to supply this access-token, so this is the identity-provider, AKA authentication server, e.g. Facebook, Google, (or implement one by your own).

The flow is (generally): the user (mobile app) tries to reach a protected resource; since it has no token, he is being redirected to the auth-server. the latter is responsible for the user/password login page, and creating the token.

If it is true - you still can implement everything by your own, without using Facebook/Google APIs, because oAuth has SPECs. However, it can be easier for you to use the providers' packages.

EDIT: reconsider the usage of oAuth

You use oAuth only if you want your webapp to support oAuth SPEC. There are several benefits, one of them is that you can use 3rd party identity provider, e.g. Yahoo! and use their identities without managing them. So if I have a user in Yahoo!, I can use your app without additional registrations (your app will have to support access-tokens from Yahoo!). But in your case, you are about to implement all the logic of identity-provider (forgot password, change password, registration, etc) plus supporting oAuth - and all of this without enjoying the benefits of oAuth at all! So - you have to reconsider the usage of oAuth...

Impulsion answered 26/1, 2013 at 21:0 Comment(7)
Not sure I understand what you are saying. I believe the resource server and authorization server will be same (Joomla in my case). I don't see why I would use Facebook or Google APIs as I don't plan to have users log into their mobile apps with FB or Google? They need to authenticate with Joomla, so wouldn't I have to build my own implementation?Arcadia
Usually in oAuth, the authorization server and the resource server are NOT the same app. Take Google, for example: you have Google Accounts (the oAuth server), and Calendar or GMail, that are applications that are "resource-servers" and uses Google Accounts as identity provider. In your case, they can be merged together if you want to - there are some cases I know that they come as one app. You want to use Joomla as the auth-server? Do Joomla serve as auth-server? (i have no idea). Or maybe you want your app that is developed using Joomla to be a auth-provider? the difference is important...Impulsion
Joomla is a CMS with its own authentication. So I have a site built in Joomla where users can login to our site and where the protected resources are (hence resource server). The server issuing the tokens to the client will also be a component (or plug-in) inside Joomla (hence authorization server). So they are the same. Why is the difference important?Arcadia
the difference is important because i mentioned two completely different use cases. so if i understand your use case, you will have an webapp that serves both as resource server, as well as authentication server. the question is - why do you want to support oAuth anyway? it does not seem to be a MUST (unless you want to support oAuth by design) why don't you consider using a regular username/password secured-webapp (no oAuth)?Impulsion
It is not a must. You bring up a good question. I assumed that Oauth2 is the right direction for native apps to communicate with my Joomla DB. Perhaps it is not, hence the lack of answers to this post.Arcadia
I've updated my answer (coz my reply here was too long...) please have a look.Impulsion
I think I've confused matters worse. I'm not implementing the logic of an identity-provider.Arcadia
I
0

You need to use their APIs as a base. They aren't going to just let you build your own API that connects to their database, that to them would look more like a password cracker than an API.

Ieper answered 28/1, 2013 at 21:6 Comment(2)
Your misunderstanding the question. I don't want connect to their database. I don't want anything to do with Google, FB, etc. I want to build a native app that will communicate with my DB.Arcadia
I'm sorry I did misunderstand your question. I'm in class but I'll think more about this.Ieper
D
0

This isn't Joomla or a tutorial, (and I'm very rusty in php) that said...

First a few caveats: * memcache isn't secure & this implementation has you putting username / password in: Be sure that it is safely behind a firewall, or else encrypt it first. Happy to give some pointers on that if you need it. * memcache isn't guaranteed not to drop data if it runs out of memory. In practice it is reliable, but your app should handle that gracefully. If you don't want to lose data like that, just substitute something like couchbase for memcache. * just returning a token in response to a login probably isn't super useful. I'd json-ize the token along with stuff like the user name, and any other info to get the app up and running without needing to make a second API call. * the code below doesn't handle error cases, I can call them all out in more detail if that isn't obvious to you.

If it were me, I'd just use memcache to persist the tokens & map that token to the username & password that was originally passed. You can use the memcache time to live to get your expiration for free.

Send username / password to the server (ideally over https). Create a random string or guid (eg: http://php.net/manual/en/function.uniqid.php or http://www.lateralcode.com/creating-a-random-string-with-php/) , this is your token Store the username / password in memcache with that token as a key Set a timeout

$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;
}

If the token is incorrect or expired, they get an null credentials back and have to login.

Edit: cleaned it up into functions that appear to work in php...

Delineator answered 2/2, 2013 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.