I've been implementing an OAuth login via the Google Identity toolkit in php. I've got as far as getting an authenticated session, the userdata, id, photo etc, which seems to be working more or less ok.
However, I'd like to be able to login using methods that don't rely on redirection on the user's browser (thinking of remote APIs for an application), but bit lost on how to achieve this.
Imagine a request which is something like:
$details = new stdClass();
$details->secret = $config->secret;
$details->client_id = $config->client_id;
$details->app_name = 'my awesome oauth app';
$details->login = array();
$details->login['email'] = 'some google account email # example.com';
$details->login['password'] = '1234';
$token = $this->do_auth($details);
if($token) {
// do stuff, setup cookies, insert token in session table etc
}
I'm using CodeIgniter. Are there any libraries that can do this..? I've seen android apps doing similar things, using custom login forms, so I'm guessing it's achievable in php.
You HAVE to redirect, it's a core essential of the way OAuth works, there is no way around this. That's why there is a redirect_uri parameter.
You only have to do this once though: when the user is logging in and you are requesting an access token. After that, you simply use curl for example to request your data.
Related
I'm writing a simple RESTful service, using Phil Sturgeon Rest Server. Can anyone provide me a solution for login using username and password. I am able to get all the json reponse without login.
Porblem 1 : $config['rest_auth'] = 'basic';
An Error Was Encountered
The configuration file ldap.php does not exist.
The same happens with $config['rest_auth'] = 'digest';
I haven't used "ldap" earlier and don't know how it works apart from a few basic information. So could you please tell me what could be the reason for this error ?
Tried out Solutions
I changed the value of $config['auth_source'] = 'ldap'; to $config['auth_source'] = ''; , Now REST Login Usernames are working for both basic and digest , ie;
$config['rest_auth'] = 'basic'; or $config['rest_auth'] = 'digest';.
$config['rest_valid_logins'] = ['admin' => '1234','sudheesh'=>'test'];
Prevailing issue : unable to use session for authentication
Tried the commented notes from Phil Sturgeon ie;
Note: If 'rest_auth' is set to 'session' then change 'auth_source' to
the name of the session variable
How the session is created in MODEL, it is here :
if ($query->num_rows() == 1) {
// If there is a user, then create session data
$row = $query->row();
$data = array(
'id' => $row->id,
'name' => $row->full_name,
'email' => $row->email,
'phone' => $row->phone,
'acc_status' => $row->rec_status,
'validated' => true
);
$this->session->set_userdata($data);
//$this->session->set_authkey('1e957ebc35631ab22d5bd6526bd14ea2');
//print_r($data);
return $data;
Question is : How can I change the 'auth_source' to
the name of the session variable ,
Right now it is $config['auth_source'] = ''
Do i have to change it to : $config['validated'] , if I do this am not getting the access , I have read here that:
If you're tying this library into an AJAX endpoint where clients
authenticate using PHP sessions then you may not like either of the
digest nor basic authentication methods. In that case, you can tell
the REST Library what PHP session variable to check for. If the
variable exists, then the user is authorized. It will be up to your
application to set that variable. You can define the variable in
$config['auth_source']. Then tell the library to use a php session
variable by setting $config['rest_auth'] to session.
Is there any suggestions ?
Problem 2 : How can I grant API access to users with a valid username and password ?
Can anyone provide me with a function or detailed information on how to implement this ?
Other Doubts :
$config['rest_valid_logins'] = ['admin' => '1234'];
The description for this 'REST Login Usernames' says if ldap is configured this is ignored.
Question : How can I use this Array of usernames and passwords for login, without configuring LDAP.
REST Login Class and Function
This says, If library authentication is used define the class and function name.
The function should accept two parameters: class->function($username, $password).
In other cases override the function _perform_library_auth in your controller.
For digest authentication the library function should return already a stored md5(username:restrealm:password) for that username.
e.g: md5('admin:REST API:1234') = '1e957ebc35631ab22d5bd6526bd14ea2'
$config['auth_library_class'] = '';
$config['auth_library_function'] = '';
Question: Can I use this to allow users with a valid username and password to access the API ? If Yes , Do you have any functions already written to help in this scenario , any help would be highly appreciated. Thank you very much .
If you know answers for any of my issues, please help. Thanks again.
Rather than attempt to address every single question posted by Sudheesh, I would like to propose an alternate solution.
Disclaimer: This is a commercial Joomla plugin, so please keep that in mind before proceeding...
Having experienced the same challenge as yourself, I ended up building a RESTful API framework for Joomla, powered by the Slim PHP micro-framework. This allowed me to leverage all the power of Slim, including it's standards-compliant routing architecture, request-type handling and much, much more. This also solved the problem of deal with authentication, access control, content management, database access, etc. because it runs on the Joomla CMS & Platform framework.
This solution provides exactly what you are looking for, easily extensible through plugins and is built on an already popular and well support RESTful API framework (Slim).
For more information on the micro-framework I used:
http://slimframework.com
For more information on the Joomla RESTful API package:
http://getcapi.org
What does it provide?
Control Panel for managing access tokens, API rate limitation and other Slim parameters
Pluggable framework allowing for easy incorporation of new web service routes (include new ones to be released soon, for MySQL, MSSQL, LDAP, etc.)
Based on Joomla. This means you don't have to worry about writing the authentication, access control, content management or other framework. It's already done!
Examples of how username and password can be passed through to create a logged in session via a URL request:
GET user/login/:username/:password
"User login authentication via Joomla authentication plugins with username and password. Note that since credentials are passed into the URL, be aware that they can be stored in server logs. API traffic must traverse a secure (HTTPS) connection."
Response: JSON
Example request:
GET https://yourdomain.com/api/v1/user/login/dynus.borvalds/3jf9LfjNdiw
Example response:
{"msg": "Authenticated","jresponse": true,"session":"1a36eab5e2b102a979918ee049f15e27","error": false,"status": 200}
The session ID can then be used to force log-out for that session using the method:
GET user/logout/:user/:session
Hope this gets you pointed in the right direction. Let me know if you have any questions.
Question about the upgrade to v2.2 of the Facebook Platform, in particular, this part:
The previously deprecated REST API has been completely removed in
v2.1, and all apps still using it must migrate to using Graph API.
For the most part, in my Android and iOS app I am not using the REST API. I'm using the Android SDK and the iOS SDK. However, I do have one exception. When I call my server to login or really do basically anything, I try to assure that the person trying to login/access data is indeed the person they say they are. I do this:
$context = stream_context_create(array('http' => array('header'=>'Connection: close\r\n')));
$response = file_get_contents("https://graph.facebook.com/debug_token?input_token=".$accessToken."&access_token=MY_APP_ACCESS_TOKEN", false, $context);
$jsonObject = json_decode($response, true);
$data = $jsonObject["data"];
$facebookId = $this->getFacebookId();
if(isset($data['is_valid']) && $data['is_valid'] === true) {
if(isset($data['user_id'])) {
if($data['user_id'] == $facebookId) {
return true;
A little bit of code missing there, but that's the gist of it. Get an access token and a facebook id. I use the access token to see if it's legitamite and the user_id assigned to that access token is the id of the person trying to get info. If so, I let them in.
My question is, am I understanding correctly that this is going away and I have to use the Graph API to somehow do the same thing? How is this done through the Graph API in PHP given an access token and facebook id from Android/iOS?
EDIT: Just realized this is actually in the 2.0 to 2.1 section, but question still stands, should I be concerned about my server side code?
Thanks!
I'm thinking I don't have anything to worry about. The approach I'm using is in the Facebook Platform docs here:
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.2#checktoken
Under inspecting access tokens. Nothing on this page talks about it being deprecated.
im building a facebook app and i want to notify the user
https://developers.facebook.com/docs/games/notifications
im using facebook php sdk
what i do:
user auths the app and accepts permission
i get the accesstoken like:
$facebook->getAccessToken()
and then i generate a long-time token like:
public function generateLongTimeToken($token){
$long_time_token_req_body = array(
"grant_type"=>"fb_exchange_token",
"client_id"=>$this->facebookOptions["appId"],
"client_secret"=>$this->facebookOptions["secret"],
"fb_exchange_token"=>$token
);
$query = http_build_query($long_time_token_req_body);
$lttreq = file_get_contents("https://graph.facebook.com/oauth/access_token?".$query);
$lttresp = parse_str($lttreq, $output);
if ( array_key_exists("access_token", $output)){
$this->logger->info("Facebook-app: Successfuly generated long_time_token");
return $output["access_token"];
}else {
$this->logger->err("Facebook-app: generating oauth long_time_token failed \n".$lttreq);
return false;
}
}
some later i use this token for background processes to post on the users wall and them all work fine
now i also want to notificate the user like that :
public function notifyUser($message,$facebookClientId,$token){
$appsecret_proof= hash_hmac('sha256', $token, $this->facebookOptions["secret"]);
$req_body = array(
"access_token"=>$token,
"appsecret_proof"=>$appsecret_proof,
"href"=>"/index",
"template"=>$message,
"ref"=>"post"
);
$query = http_build_query($req_body);
$url = "https://graph.facebook.com/".$facebookClientId."/notifications?".$query;
$lttreq = file_get_contents($url);
return $lttreq;
}
but when i try to notify the user i always get empty data back
when i open the url in browser with all parameters facebook returns the same
{
data: [ ]
}
so i have no idea whats going on,when i look on SO i only find about people posting to sites but i want to notify the user itself
thanks for any help
First, from the Facebook docs:
Currently, only apps on Facebook.com can use App Notifications.
Notifications are only surfaced on the desktop version of
Facebook.com.
Also, an App Token is needed, not a User Token.
Btw, file_get_contents is very bad, use CURL for Facebook. May be another reason why it does not work. A basic example of using CURL with the Facebook API: http://www.devils-heaven.com/extended-page-access-tokens-curl/
Additional Info: I recently wrote a blogpost about App Notifications, it is in german but the small code part may be interesting for you: http://blog.limesoda.com/2014/08/app-notifications-facebook-apps/
I'm using http://wordpress.org/extend/plugins/simple-twitter-connect/ to use twitter on a wordpress blog. But I've a problem with request tokens.
Here's my code:
$to = new TwitterOAuth($options['consumer_key'], $options['consumer_secret']);
$tok = $to->getRequestToken();
function getRequestToken() {
$r = $this->oAuthRequest($this->requestTokenURL());
$token = $this->oAuthParseResponse($r);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}
But after clicking on the sign in button, Twitter returns this:
'Whoa there!
There is no request token for this page. That's the special key we need from applications asking to use your Twitter account.'
The URL is https://twitter.com/oauth/authenticate?oauth_token=
Presumably the missing value is the problem.
I'm hoping to then allow the logged in user to tweet from the site, yet I haven't even gone near that with the above problem.
Any ideas??
Haves you tried logging into Twitters Developer site (https://dev.twitter.com/) to get your access token? If not you need to create an app which will allow access from your site to twiiter. The Directions on the developer site are pretty easy to follow.
Im trying to connect from PHP(Zend Framework) code to an aspx Web Service. I need to send via post a few parameters to the page( email, password). I have tried to use Zend_Http_Client, and do this:
$client = new Zend_Http_Client('https://thesiteurl.asmx/Login');
$client->setMethod(Zend_Http_Client::POST);
$client->setAuth($username, $password);
$client->setParameterPost(array('email' => 'email', 'password' => 'password'));
$response = $client->request();
$this->view->response = $response;
where $username, $password are the username and password I use to log in to the web service(it has a pop-up window that asks me for username and password).
This code gives me the unauthorized page. So im asking where am I using the site username and password wrong? How can I use them?
edit:
The Auth is auth-basic.
Edit2:
I talked to the owner of the web service he says that everything is UTF-8 is this a problem, isnt it is a default? If not how do i do that?
You could check if a referer-header is needed, or it might be that it also needs a cross-site request forgery number. Simply dump the request that is made by your browser when you login and dump the request that your script is generating, compare those and it should work out.
For the browser-request dump you could use livehttpheaders plugin for firefox.
Depends on what that pop up box really is.
You probably need to study the HTTP Authentication. Currently, Zend_Http_Client only supports basic HTTP authentication. This feature is utilized using the setAuth() method, or by specifying a username and a password in the URI. The setAuth() method takes 3 parameters: The user name, the password and an optional authentication type parameter. As mentioned, currently only basic authentication is supported (digest authentication support is planned).
// Using basic authentication
$client->setAuth('shahar', 'myPassword!', Zend_Http_Client::AUTH_BASIC);
// Since basic auth is default, you can just do this:
$client->setAuth('shahar', 'myPassword!');
// You can also specify username and password in the URI
$client->setUri('http://christer:secret#example.com');
Source.
If this is not an HTTP auth and is somothing else, try to use cURL, wget or linx to see exactly what is happening on the page and now you can simulate it using Zend_Http_Client.
Sometimes you have to send cookies, execute some Js or follow some redirects. Zend_Http_client can do all this things.
have you tried this?
$config = array(
'adapter' => 'Zend_Http_Client_Adapter_Socket',
'ssltransport' => 'tls'
);
$client = new Zend_Http_Client('https://thesiteurl.asmx/Login', $config);
$client->setAuth('shahar', 'myPassword!', Zend_Http_Client::AUTH_BASIC);
also I am confused, is this popup a http basic auth, or something that is self designed?
since for basic auth you normally wouldn't send any post params...
the real URL of the site would help very much for finding the solution...
If you can access the servis using browser, use firebug to check the request and response. There might be some other parameters involved, eg cookie.
The best way to tackle these things is by just using the packet sniffer (tcpdump, ethereal, ...) to see what's happening on the line. Then compare the request/response you observe in a working scenario (e.g. from your browser) to the request/reponse which is not working.
This will very quickly reveal the precise difference at the HTTP level. Using this information you can either find out what to fix in your handling of Zend_Http_Client, or find out that Zend_Http_Client doesn't support a particular feature or authentication scheme.