How to sign HTTP requests with user credentials for mobile app and backend server communication? - php

We have a pretty standard scenario - a mobile app communication with a backend PHP server API via HTTP POST and GET. A user must login in mobile app in order to do anything, so every request from mobile app to our server needs to be signed with user credentials. Userid and password are saved in mobile app internal settings after successful login, so a user does not need to reenter it again.
Previously, backend PHP webservices were developed by other guys, but now we need to implement it ourselves. When looking at previous projects, they required to pass user credentials for every request. I'm posting several request examples below. All data insert/update web services use POST, but userid and pwd are passed inside body with other data (Save Car). All data select services pass userid and its password via GET params.
Is it the best and secure way? Maybe we should put sha1(userid+password=salt) into HTTP authorization header and leave userid in body (because we need to select user pass from database in server)? Or maybe we could use OAuth 2 in mobile app for signing HTTP request (generating userid+pass+... to authorization header) and use OAuth 2 in backend to generate the same hash and check if it's the same? I could'n find any straightforward way how to use OAuth 2 for PHP just for signing request, so any help would be appreciated :) Also, related info about what libraries to use for iOS/Android development would be also appreciated.
LOGIN
HTTP method: POST
URL: http://mybackend.com/login
BODY:
{ "uid" : 123,
"pwd" : "3CB3E2E6AECA48C41000119767B561F5E9E66229" // contains sha1(pass+salt)
}
GET CAR LIST
HTTP method: GET
URL: http://mybackend.com/getCars?uid=123&pwd=3CB3E2E6AECA48C41000119767B561F5E9E66229
SAVE CAR
HTTP method: POST
URL: http://mybackend.com/saveCar
BODY:
{ "uid" : 123,
"pwd" : "3CB3E2E6AECA48C41000119767B561F5E9E66229",
"car" :
{ "id" : 111,
"name": "My car"
}
}

I may ask if user can change password in app then is it updating that password with the saved one in app code?
better way to post data as make a directory of access_token and use userid and password in it.
as for Example :
{
"access_token":{
"uid" : 123,
"pwd" : "3CB3E2E6AECA48C41000119767B561F5E9E66229"
},
"saveCar" : {
"id" : 111,
"name": "My car"
}
}
and at the sever side php code be easy to access your all url with this accesstoken by checking with database and allowing you access to do the saveCar in database.
else from sever side you will have error message as access failed to login try again with login.
and use it in post method with all requests.
will be good for security type.
POST method is one for PHP data security.
no other thing you need for this.
Instead of using GET HTTP request for car list, you can POST the access token to your url as
{
"access_token":{
"uid" : 123,
"pwd" : "3CB3E2E6AECA48C41000119767B561F5E9E66229",
}
}
to your URL for Carlist.
http://mybackend.com/getCars? from that post method, do the code for as in result of this post method returns the list of cars.
Thanks, Hope this description can help you.

Related

Yii2 - Do a http form POST on external URL and redirect to it

I have an application on Yii2.
I have an external vendor i want to redirect. For example, i am encrypting the current user info, and want to send that to the external vendor, so the user information is automatically populated on his website.
Everything works fine if i do that on the front end side using JS.
The problem i have is only my app server is whitelisted to the vendor. So i need to make the redirection happen on the backend.
I tried several method, and even with Guzzle HTTP, and it doesn't redirect.
TO be clear, i am not looking for a simple redirect, it is a form post on external URL.
I went though this post, but the problem remain the same...
Yii2 how to send form request to external url
Does anybody faced this issue?
If I understand you correctly, you want to POST data received from your frontend to the server of a third party company (let's call them ACME). Your webserver is whitelisted by ACME but your clients are not (which is good). You want to show a page on your server and not a page on the ACME server after the POST, right?
You have to send the data with a separate request from your server to the ACME server. You cannot create a HTML <form> and put the ACME server in the action parameter of it, because the request would be sent from the client and not your backend, failing at the whitelist. After you validate your client input, you can send it with guzzle to ACME.
With the status code you can decide if your request was successful or not. You can read more about guzzle here
The code sample below shows how you could POST the $payload (a fictional blog post if you will) as JSON to the ACME server and output a line with the request result.
$payload = [
'username' => 'john.doe',
'postContent' => 'Hello world',
];
$client = new GuzzleHttp\Client();
$response = $client->post('https://acme.example.org/endpoint',['http_errors' => false, 'json' => $payload]);
if($response->getStatusCode() === 200){
echo "Request OK";
}else{
echo "Request failed with status ".$response->getStatusCode();
}

How to retrieve device registration ID by using PHP (web) to avoid MismatchSenderId?

This is my code on the app on phonegap to obtain the registration ID. The registration ID is always obtained successfully.
const push = PushNotification.init({
android: {
},
browser: {
pushServiceURL: 'http://push.api.phonegap.com/v1/push'
},
ios: {
alert: "true",
badge: "true",
sound: "true"
},
windows: {}
});
push.on('registration', function ( data ) {
recordRegistrationID( data.registrationId ); //Pseudo
});
push.on('notification', function ( data ) {
// data.message,
// data.title,
// data.count,
// data.sound,
// data.image,
// data.additionalData
});
push.on('error', (e) => {
// e.message
});
Then I try to send a push notification to that device with the stored registration ID from my PHP server (example.com) by cURLing it to Firebase Cloud Messaging API, it always returns MismatchSenderId.
{"multicast_id":6660509895358893455,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"MismatchSenderId"}]}
I already tried to compile the .APK and run it on my mobile device. I always successfully get the token, but the message can never be sent to that registration ID retrieved by the PhoneGap app.
Doing more research, it seems like that because PhoneGap actually retrieves the registration ID but it ties to PhoneGap itself as a sender, so other senders won't work.
Am I correct to assume this? If this is the case, how can I obtain the registration ID using PHP instead of PhoneGap, for Firebase Cloud Messaging?
Thank you.
Doing more research, it seems like that because PhoneGap actually retrieves the registration ID but it ties to PhoneGap itself as a sender, so other senders won't work.
This seems like an odd behavior. The token generated is tied to an app instance and the Firebase project. Can you provide the link where this is mentioned? It doesn't make sense for the token associated to change to a different sender at all.
With that said, there is currently no way to get the registration token from your backend. As I mentioned above, the token is tied to the app instance, so it can only be generated on the client app side.

Why am I getting error when I use Postman and oauth2 for login access case in apiagility?

I am new to Zend Framework 2. I am trying to get the login access scenario working with Postman (chrome extension). I have gone through the forum but I'm not sure if I'm missing something or not. So here are the steps that I have taken so far:
In MYSQL I have set up the tables accordingly and there is a user with the following fields in the oauth_clients table:
client_id : testclient
client_secret : testpass
redirect_uri : /oauth/receivecode (I'm not sure about the value of
this one could someone please shed some light on this?)
grant_type : password ( I want to use the service for authentication
and authorization to access a website or login access scenario)
The rest of the fields are NULL. No other entries in other tables.
I set the parameters in Postman like this:
Authorization : Oauth2
Headers:
Accept : application/json
Content-Type : application/json
The raw body is like:
{
"client_id":"testclient",
"client_secret":"testpass",
"grant_type":"password"
}
I post the request to:
www.dummy.dev/oauth/authorize
When I post the request this is what I get:
{
"type": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
"title": "invalid_request",
"status": 302,
"detail": "Invalid or missing response type"
}
Why do I get this error message?
This error is triggered here in the OAuth2 AuthorizeController.
The controller checks whether the $response_type is valid. If not it returns this error message.
On line 313 you see:
protected function getValidResponseTypes()
{
return array(
self::RESPONSE_TYPE_ACCESS_TOKEN,
self::RESPONSE_TYPE_AUTHORIZATION_CODE,
);
}
Those constants are defined in the AuthorizeControllerInterface:
const RESPONSE_TYPE_AUTHORIZATION_CODE = 'code';
const RESPONSE_TYPE_ACCESS_TOKEN = 'token';
So somewhere during the handling of your request this $response_type value is not set correctly. It should either be set as token or code for the request to validate correctly. Not sure where in your config you did something wrong but with this information you should be able to find the problem.
redirect uri is not necessary and could be left null in the database as well. The correct uri to POST is www.dummy.dev/oauth and the raw parameters in Postman are:
{
"client_id":"dev.dummy",
"username":"testclient",
"password":"testpass",
"grant_type":"password"
}
The value of password is stored and encoded (with bcrypt) in the database. client_id and client_secret are not important in this scenario as my own website is the client of my API.

Trying Prebinding converse.js with php to an openfire server

So I have a web site where you can login with a username and a password and I would like that with that one login, a session could be generated for converse.js
I've been reading the documentation and the SSO Support and I ended in an example repo for prebinding with php. link
I prepared an object wich should be the model I'll call from my controller, but there are some parameters I'm not sure what they are.
$xmppPrebind = new XmppPrebind('your-jabber-host.tld', 'http://your-jabber-host/http-bind/', 'Your XMPP Clients resource name', false, false);
$xmppPrebind->connect($username, $password);
$xmppPrebind->auth();
$sessionInfo = $xmppPrebind->getSessionInfo(); // array containing sid, rid and jid
The 3rd parameter on the XmppPrebind Constructor 'Your XMPP clients resource name' what is that?
Also when doing the connect function the parameters $username and $password...are those the one I get from my loging form (the one on my website) or some valid user & password pair on the openfire server?
'Your XMPP Clients resource name' = Any name you want, example: myWebChat
"Also when doing the connect function the parameters $username and $password...are those the one I get from my loging form (the one on my website) or some valid user & password pair on the openfire server?" Use prebind to make user autologin to your xmpp server when they login to your website, so the account must valid on xmpp server.
$sessionInfo will have sid rid and jid. Third parameter will be added to jid. You will get something like:
"you#conference.conversejs.orgYour XMPP Clients resource name"
So just set it empty.
I guess only first or third parameters should be set, not both in one time.

PHP:give json data to only phonegap apps?

so i have a domain www.example.com and i have an app that access some dir in the domain to get json data for example www.example.com/phonegapdata/index.php
anyone can get the data if they want by typing the url or via getjson i am using the following code
$.getJSON(url,{ name: "John", time: "2pm" }, function(data) {
console.log(data);
}); //getJS
How can i make it secure so that only my app, can access it.?
Is there a way to make it more secure.?
The way to "secure" any web endpoint is:
1) restrict access to files, directories, and/or service endpoints.
This, in turn, means that you must:
2) provide some means of authentication. The server needs to know "who" is requesting access in order to permit or deny that access.
SUGGESTIONS:
Familiarize yourself with "HTTP Basic Authentication"
Configure your web site to authenticate. Verify that you can access the items you want with a username and password in your browser. Verify that you cannot access the items you want to restrict without the right credentials.
If you don't want users to enter a username and password themselves, then simply program your phonegap app to send username and password in the HTTP headers when it connects to your server. For example:
PhoneGap FileTransfer with HTTP basic authentication
authHeaderValue = function(username, password) {
var tok = username + ':' + password;
var hash = btoa(tok);
return "Basic " + hash;
};
options.headers = {'Authorization': authHeaderValue('Bob', '1234') };
Once you get this working, you can substitute something more sophisticated. But this should get you started in the right direction.

Categories