Log out user from Android app when user signs in on website - php

I have an Android app and a website that offer the same content to a user. I'm trying to accomplish the following:
If a user signs in on the website the Android app should sign him out automatically and if the user signs into their account from the Android app then the website should sign them out. This is to make sure at one time the user can access either the web app or the Android app, not together.
I'm looking for best practices and solutions to accomplish this.
Here's what I have come up with:
When the user logs in either from Android or website I update a field in the database called "login_device" this will be either "web" or "mobile" depending on the situation.
If "login_device" is "mobile" and the user logs in from the website it will change to "web" and the Android app will log out the user.
If "login_device" is "web" and the user logs in from the Android app, this value changes to "mobile" and the user is logged out from the web.
Also, I have created a web service called "ping" for the Android app.
But, in this approach there would be a need for the Android app to maintain a constant connection with the server to check the value of "login_device".
Here's the ping service code:
<?php
require_once 'transact/info.php';
require_once 'transact/database.php';
require_once 'transact/func.php';
$data = file_get_contents('php://input');
$json = json_decode($data);
$id = mysql_real_escape_string($json->{'user_id'});
$query = 'select login_device from users where id = '.$id;
$result=mysql_query($query) or die('error getting admin details : '.mysql_error());
$row = mysql_fetch_array($result);
$array = array("login_device" => $row['login_device']);
print( json_encode($array));
?>
So, my questions are:
Q - In this approach how can I maintain a constant connection with the sever to check the value of "login_device:
Q - Is there a better and more standard way of trying to accomplish the above?
Thanks for helping out!

Q - In this approach how can I maintain a constant connection with the sever to check the value of "login_device:
Define a standard time interval in which even if someone logins to the website, they dont really have enough time to break any rules (according to what your apps are doing) (for example 10 seconds), and ping the website in this interval. The architecture of the mobile apps is usually based on REST technologies. That said, there is no really permanent connection. The closer you can get is very close together pings. So, you only need to define "how often is often enough for me"
Q - Is there a better and more standard way of trying to accomplish the above?
No, because this is not a usual requirement. Most applications/websites right now do not disallow permanent usage from multiple devices. So how you have started doing it seems like the best solution

Have you considered building a website using node.js and then turning it into a mobile app by wrapping it in Phone Gap and XCode to turn it into Droid and iOS apps respectively. Node.js will keep a synchronous connection open to your app, which will allow push events when the login status of the user changes.

Related

Real time chat in PHP +Redis +Pub/Sub +WebSockets (+NodeJS)

I want to develop real time chat with channels and these are my needs:
PHP backend to manage site
Redis as session and data primary storage
Pub/Sub to send messages only to channel's interested users
one WebSocket connection with which the messages will be send and received.
(optional) NodeJS to use great npm packages like timesync or socket.io
I see two different architectures to achieve this:
with Socket.io
with Crossbar.io
These are my questions:
Which architecture I should choose and why?
The key is the user id cannot be obtained from client, because it can be malformed. So in the first architecture I think on every socket message I should attach PHPSESSID value from cookie and on sever-side retrieve PHP session from Redis. Am I right or there is better way to get user id?
I wonder if getting user id in second architecture can be done differently?
Edit:
I choosed Crossbar.io, cause it is very powerful and allows to communicate many different language applications in real time. After studying examples, I come up with this:
On every login user have generated secret key in database.
PHP client (Thruway) connect to Crossbar server and register custom WAMP-CRA authenticator
User's browser connect to Crossbar server and is challenged. Secret and auth_id (user id) are loaded from DB with page load, so it
can accomplish challenge and send response.
PHP authenticator search in DB for user with provided secret and id equal to auth_id. If there is, then it successfully authenticate
session. Now we can trust that auth_id is real user id.
These are my question:
How I can get auth_id on subscribe?
I also added cookie authentication and browser is remembered after authentication. But when I look in Chrome DevTools there is any cookie nor value in local storage. Even after clearing cache my browser is still remember by Crossbar. I wonder how it is possible?
Edit2:
Maybe I was misunderstood, but the main question was choosing appropriate architecture and getting trusted user id. There was no attention so I awarded bounty and after that I was downvoted. I read a lot about real-time apps and finally decided to use Crossbar.io, so I edited question to be related to it. Then people started upvoting, proposing another architectures, but not really answering my questions. After all I managed to do it myself and presented my answer.
About getting user id:
Every real-time chat examples which I saw, was getting id from client. It is unsafe, because client easily can manipulate it, so I needed to find another method. After reading WAMP specs I finally figured out that I have to authenticate user not only in app, but also in Crossbar.io. I choosed the dynamic WAMP-CRA method and implemented as following:
PHP app connect to Crossbar server and register custom authenticator (similar to example)
After user login in app there is generated secret key for him and saved in database. After logout, key is destroyed.
Workflow:
Every loaded page contain user id and secret key loaded from db:
<script>
auth_id = '<?php echo $user->id ?>';
secret_key = '<?php echo $user->secret_key ?>';
</script>
User browser connect to Crossbar.io server and get response with challenge from custom authenticator.
It calculate signature using key and send along with auth_id to Crossbar.io server
Authenticator gets from DB secret for provided auth_id and calculate signature. Then signatures are compared and if they are equal then authentication is successfull.
Now auth_id contain user id and we can trust its value. Now you can refer section 'How I can get auth_id on subscribe?'.
Answers:
How I can get auth_id on subscribe?
By default publishers and subscribers does not have any knowledge about each other, but documentation show there is option to change it by configuring disclosure of caller identity. Then you can get auth_id from callback details:
PHP:
$onEvent = function ($args, $argsKw, $details, $publicationId) use ($session) {
$auth_id = $details->publisher_authid;
...
}
$session->register('com.example.event', $onEvent);
JS:
function on_event(args, kwargs, details) {
auth_id = details['publisher_authid'];
...
}
session.subscribe('com.example.event', on_event);
I also added cookie authentication and browser is remembered after authentication. But when I look in Chrome DevTools there is any cookie nor value in local storage. Even after clearing cache my browser is still remember by Crossbar. I wonder how it is possible?
First of all, clearing cache and hard reload does not remove cookies. When I was asking this question there was any cookie presented, but today I can see cbtid:
There was Chrome update two days ago, so maybe this was caused by bug in previous version.
I deeply light Streamer which is used by NASA to forward truck loads of data per second.The most reliable server for real-time messaging.
Power web, mobile, tablet, desktop, and IoT apps.
Optimized data streaming for web and mobile.
Lightstreamer enables several forms of real-time messaging. It is flexible enough to be used in any scenario, including mission critical applications.
► Real-time Data Push and Web Sockets
► In-App Messaging and Push Notifications
► Pub-sub with fan-out broadcasting and one-to-one messaging
► Firewall and proxy friendly
► Adaptive bandwidth throttling
As for your first question to get the auth_id on subscription , just monitor connection subscriptions then store tier upon successful connection.
Also cookies are not recommended , use jwt.JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.Authentication is one of the big parts of every application. Security is always something that is changing and evolving.JWT helps you solve that concern.Since it is stateless.
PHP Ratchet is one of the best implementations I've used for real-time communications via WebSockets. Its based on ZMQ Sockets which is used in several online gaming applications and chat applications.
The following examples will get you started pretty quick and will answer your questions around auth_id and subscriptions:
http://socketo.me/docs/hello-world
http://socketo.me/docs/push
Overview of the Architecture:
http://socketo.me/docs/push#networkarchitecture
I would advice creating individual connections(toppics) per conversation as it doesn't really take a hit on performance and will add an additional layer of security per chat.

Laravel 5.2 live chat with socket.io and redis private message

TLDR; best solution for private instant messenger with laravel.
So I have a live real time chat working on my laravel site, However at the moment I don't have the ability to private message, its located on the home page and every time someone connects their socket.id changes The code I used and modified was from this tutorial. (I can copy paste it here if you wish I was not to sure about the rules regarding that)
http://itsolutionstuff.com/post/laravel-52-chat-message-module-using-socketio-redis-express-and-nodejs-from-from-scratchexample.html
I have no idea where to go about settings this up between 2 users as a private chat and just wondering if anyone else has ended up getting an instant messenger type system working with laravel and if so any info would be appreciated - it does not have to be socket but I was wondering is ajax a bad way of going about it.
I ended up creating each user who signs in a room of their own using a random token.
When someone requests to pm them it is announced and they have the open to start a chat (a new lobby).
It then combines both tokens using their user ids in which order to combine them as the lobby.
I have also save each thread in the db using this method.
When a token expires it updates the token in the DB also.
I am sure this is not secure, however it is not enterprise or even used publicy more so a test.
If anyone else has a more secure or better way let us know.

Possible issues with centralizing the login/registration

I've build two seperate browsergames and I want them to share the same login system. So that if you have one account which you use for both games. I want this because of payment reasons (if they buy something I have to pay per website so I want all payments to come from one website) and user experience (why sign up multiple times?).
But when they first sign up and login I do not want to redirect them to the centralized system because I want the sign-up/login-proccess to be as simple as possible because I'm afraid they'll lose interest.
So I was thinking about letting them sign in to the website normally and then using cURL to send the requests to the centralized website by building an API.
I am however wondering if this is a good approach because none of the websites are on the same network. I guess I'll have to build the centralized login system in such a way that it only accepts requests from the domains the games are on. But are there any other things I have to worry about? How should I send for example passwords? Because sending them plain text seems like a horrible idea so I guess I'll have to hash them on the side of the game. I guess I'll have to make a small copy of the users table for for example the username and user_id.
I don't want to use for example OpenID or Facebook Connect or something because that does mean redirecting to an external system (which is bad for user experience) and the average age off players on the website is about fourteen, so they have no clue about OpenID and I don't want to force them to connect their Facebook accounts to my websites.
Also I'm sorry if I'm unclear or writing in bad English, I'm not a native and having a hard time expressing myself the right way.
Thanks in advance!
If I were you, i'd create a API for registration system.
Website A (game1) uses that API to create accounts and verify them, same does the website B.
API would validate data, respond with errors (username taken etc), or return success messages. It should be protected (LAN access only or some authentication)

Creating an Api-Centric Application, my own doubts

I am trying to wrap my head around all this "api-centric" concept and somehow, for various reasons(after turning SO upside down) i am not able to find answers by my own, so i hope you can help me :)
Here it is, as part of a personal project i need to create something like a social application website, i say "like" because it's just a small project, nothing too fancy.
The idea i have in mind is that i create a rest service, say something like http://api.domain.com/v1/ with all the needed methods for resources (create/delete/update/read).
Now, after this service will be created, i need to create my website, say http://www.domain.com/ and this website will communicate with my api.domain.com for each action it does. If a new user registers, send the data to the api server, process it, return an answer and so on.
Then, after the website is created, i am planning to use phonegap to create a native application for iphone and android. These mobile applications, will basically act just like my website does, connect to the api server and do various actions.
This is pretty simple if no authorization is involved, so anyone who knows the api endpoints would be able to manage all the resources, thing that as you would guess, i don't want, so i have to implement some kind of authorization mechanism and i am not really sure what to use.
I am thinking to implement OAuth2 so that my api act as a oauth provider, then my website/mobile apps will connect to the api, get authorized and then do their job.
Is this a good approach, any thoughts?
Next, let's say i stick with oauth and everything works okay, what if i want to give my users the opportunity to create their own apps to access info about the other users/or their own data(basically i have a public api, why not taking advantage of that), then the user that will install the app will need to approve it in order to get access to his info. I know this is possible with oauth(since facebook/twitter/others does it), the question is, how do i differentiate between simple user created apps and my own ones(like the website and mobile apps)? Is this separation doable by providing various "scopes" when requesting permssions?
If not, what other approach should i use?
I'm not too experienced with oauth, so maybe some of the questions are a bit wrong, hopefully you get the point of my problem.
If it helps, i'll use PHP 5.4 with Yii framework, Apache 2(mod ssl available), MySQL.
Thanks :)
Yii provides CWebService (SOAP), you can use that, or create your own REST API indeed.
I created a API myself, the same way you want to do it.
For safety purposes i'm logging in with a api username and a api password using CUserIdentity:
if (Yii::app()->apiuser->isGuest) {
if (!empty($_POST['apiUser']) && !empty($_POST['apiPassword'])) {
$identity = new ApiUserIdentity($_POST['apiUser'],$_POST['apiPassword']);
$identity->authenticate();
if($identity->errorCode===ApiUserIdentity::ERROR_NONE)
{
Yii::app()->apiuser->login($identity); // Login for 30 minutes
$responseData['success'] = 1;
$responseData['sessionId'] = Yii::app()->session->sessionID;
} else {
$responseData['error'] = 'Incorrect username and/or password';
}
}
}
The POST data is coming from the app it uses the api. The SessionId is passed back to the app, so a next login isn't necessary. If you're using CURL to make the api request you can send the session ID back to the next api request using:
$strCookie = "PHPSESSID=".$sessionId."; path=/";
// Set the COOKIE files
curl_setopt($ch, CURLOPT_COOKIESESSION, true );
curl_setopt($ch, CURLOPT_COOKIE, $strCookie);
This way the session is maintained every next request.

Alternative log in & authentication methods (for elderly people)

I'm designing a simple web app for some elderly family members, 1 of whom has Alzheimer's. The end goal is to provide them each with a tablet (probably Android but irrelevant for this problem) that would be stripped down to ideally 1 bookmark on the home screen which opens my web app.
What I am looking for are ideas on how to identify the user without the conventional username/password methods. With their condition I know that remembering an username is going to be almost impossible, let alone a password. Ideally I would recognize the device and relate that to a specific user.
There will be other users on the app that access it through normal methods (username+password on PC/mobile/tablet), which I'm handling with Zend_Auth. It's just these 2 users who I am concerned about identifying.
Security isn't a huge concern as the data will not be sensitive in any way, but I still need to differentiate between users.
I am building this in php with Zend Framework. I'm really looking for more ideas than specific code, although anything based in php or javascript would be great. Any ideas or suggestions would be greatly appreciated. Thanks for your help
These advice are only valuable if security is not an issue :
On the bookmarks page, insert a token in the link, which you will use to authenticate the users.
if you can, check in the background for IP/user agent (if there is only one device that needs this simplified auth process, and assuming it's connection uses a fixed IP address)
And a simple idea if you have multiple users using the same device :
on your bookmark page, put a picture of each user
make it clickable, with the token discussed above in the href of the link.
That's simple to implement and easy to remember.
Hope that helps !

Categories