PHP - Oauth As An Authentication Method
Hi guys,
I am building my new web-service in a way that makes it use its own API (like Twitter is now). However I have no idea and cannot find a helpful resource on how to turn oAuth 2 (PHP) into an Authentication method and not just for authorizing the display of content. Any and all help is much appreciated. Cheers in advance Similar TutorialsOVERVIEW: The code is about making call to the escreen web service using SOAP and Curl with client authentication required. Currently I am not getting any result only HTTP 403 and 500 errors. The call requires client authenticate cert to be on the callng site. CODE: $content = "<TicketRequest> <Version>1.0</Version> <Mode>Test</Mode> <CommitAction></CommitAction> <PartnerInfo> <UserName>xxxxxxxxxx</UserName> <Password>xxxxxxxxxxx</Password> </ PartnerInfo> <RequestorOrderID></RequestorOrderID> <CustomerIdentification> <IPAddress></IPAddress> <ClientAccount>xxxxxxxxxx</ClientAccount> <ClientSubAccount>xxxxxxxxxx</ClientSubAccount> <InternalAccount></InternalAccount> <ElectronicClientID></ElectronicClientID> </CustomerIdentification> <TicketAction> <Type></Type> <Params> <Param> <ID>4646</ID> <Value></Value> </Param> </Params> </TicketAction> </TicketRequest>"; $wsdl = "https://services.escreen.com/SingleSignOnStage/SingleSignOn.asmx"; $headers = array( "Content-type: text/xml;charset=\"utf-8\"", "Accept: text/xml", "Cache-Control: no-cache", "Pragma: no-cache", // "SOAPAction: \"\"", "Content-length: ".strlen($content), ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $wsdl); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_VERBOSE, '1'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $content); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, '1'); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, '1'); //curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml")); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //curl_setopt($ch, CURLOPT_HTTPHEADER, array('SOAPAction: ""')); curl_setopt($ch, CURLOPT_CAPATH, '/home/pps/'); curl_setopt($ch, CURLOPT_CAINFO, '/home/pps/authority.pem'); curl_setopt($ch, CURLOPT_SSLCERT, 'PROTPLUSSOL_SSO.pem'); curl_setopt($ch, CURLOPT_SSLCERTPASSWD, 'xxxxxxxxxxxx'); $output = curl_exec($ch); // Check if any error occured if(curl_errno($ch)) { echo 'Error no : '.curl_errno($ch).' Curl error: ' . curl_error($ch); } print_r($output); QUESTIONS: 1. I need to call the RequestTicket method and pass the XML string to it. I don't know how to do it here(pass the method name to call). 2. For client authentication they gave us three certs, one root cert, one intermediate cert and a client authentication cert PROTPLUSSOL_SSOpem(it was a .pfx file). Since we are on linux we converted them to pem . In curl calls I could not find way to how to include both the root cert and the intermediate cert ,so I combined them by making a new pem file and copying the intermediate cert and them the root cert and naming it authority.pem . I am not sure whether it works or not and would like your opinion. 3. For the current code Iam getting the error Error no : 77 Curl error: error setting certificate verify locations: CAfile: /home/pps/authority.pem CApath: /home/pps/ If I disable the curl error message,I am getting blank page with page title 403 - Forbidden. Access is denied. If I comment out the CURLOPT_CAPATH and CURLOPT_CAINFO lines it gives http 500 error page with the message as content and the following at the top. > HTTP/1.1 500 Internal Server Error. Cache-Control: private Content-Type: text/html Server: Microsoft-IIS/7.5 X-AspNet-Version: 1.1.4322 X-Powered-By: ASP.NET Date: Thu, 02 Sep 2010 14:46:38 GMT Content-Length: 1208 If I comment out as above and also CURLOPT_SSLCERT and CURLOPT_SSLCERTPASSWD it gives 403 error with the message as content. So I would request you to help me out by pointing out whats wrong with the current code. Thank you. Is anyone able to get this https://github.com/csrui/oauth2-php oAuth PDO example to work? I cannot see where to enter the DB details. Thanks in advance. Good day Campers!
Having spent the better part of my day trawling the internet for an answer I have gotten nowhere so have come to you lovely people for help.
I found a nice little tutorial on PHP gang that would allow me to update my twitter feed from my website using PHP and OAuth.
I set up my twitter app with no issues and generated the API keys. Set the App to 'read/write' permissions and then regenerated the keys
The app is marked to "Allow this application to be used to Sign in with Twitter"
The issue is that when I click the little button to sign in to twitter, the page redirects but displays the generic "Cannot connect to Twitter" error message that has been defined in the code. I do not get asked to "Allow" the script to connect to twitter like it seems to do in the demo.
The PHPGang solution has 4 bits of script so I'm wondering if it has something to do with this as I understand the Abrahams script has slightly more so I do wonder if something is missing. I'm not sure. One of the main problems I am facing is that I have never actually done this before so I don't know where I have gone wrong or what I am even looking for help wise......
I have the following scripts:
callback.php
<?php /** * Take the user when they return from Twitter. Get access tokens. * Verify credentials and redirect to based on response from Twitter. */ session_start(); require_once('oauth/twitteroauth.php'); require_once('config.php'); if (isset($_REQUEST['oauth_token']) && $_SESSION['oauth_token'] !== $_REQUEST['oauth_token']) { $_SESSION['oauth_status'] = 'oldtoken'; header('Location: ./destroysessions.php'); } $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $_SESSION['oauth_token'], $_SESSION['oauth_token_secret']); $access_token = $connection->getAccessToken($_REQUEST['oauth_verifier']); //save new access tocken array in session $_SESSION['access_token'] = $access_token; unset($_SESSION['oauth_token']); unset($_SESSION['oauth_token_secret']); if (200 == $connection->http_code) { $_SESSION['status'] = 'verified'; header('Location: ./index.php'); } else { header('Location: ./destroysessions.php'); } ?>config.php <?php /** * @file * A single location to store configuration. */ define('CONSUMER_KEY', 'MY CONSUMER KEY'); define('CONSUMER_SECRET', 'MY SECRECT CONSUMER KEY'); define('OAUTH_CALLBACK', 'URL OF WHERE I AM REDIRECTING TO'); ?>destroysessions.php <?php /** * @file * Clears PHP sessions and redirects to the connect page. */ /* Load and clear sessions */ session_start(); session_destroy(); /* Redirect to page with the connect to Twitter option. */ header('Location: ../index.php'); ?>index.php <?php require_once('oauth/twitteroauth.php'); require_once('config.php'); if(isset($_POST["status"])) { $status = $_POST["status"]; if(strlen($status)>=130) { $status = substr($status,0,130); } $access_token = $_SESSION['access_token']; $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $access_token['oauth_token'], $access_token['oauth_token_secret']); $connection->post('statuses/update', array('status' => "$status")); $message = "Tweeted Sucessfully!!"; } if(isset($_GET["redirect"])) { $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET); $request_token = $connection->getRequestToken(OAUTH_CALLBACK); $_SESSION['oauth_token'] = $token = $request_token['oauth_token']; $_SESSION['oauth_token_secret'] = $request_token['oauth_token_secret']; switch ($connection->http_code) { case 200: $url = $connection->getAuthorizeURL($token); header('Location: ' . $url); break; default: echo '<div class="par">Could not connect to Twitter. Refresh the page or try again later.</div>'; } exit; } if (empty($_SESSION['access_token']) || empty($_SESSION['access_token']['oauth_token']) || empty($_SESSION['access_token']['oauth_token_secret'])) { echo '<a href="./index.php?redirect=true"><img src="./images/lighter.png" alt="Sign in with Twitter"/></a>'; } else { echo "<a href='destroysessions.php'>Logout</a><br>"; echo '<div class="par">'.$message.'<div> <form action="index.php" method="post"> <input type="text" name="status" id="status" placeholder="Write a comment...."> <input type="submit" value="Post On My Wall!" style="padding: 5px;"> </form>'; } ?>Now, I am unsure if there is anything wrong with the API keys I have generated or if there is something missing. Is there anyone who can point me in the right direction or offer some advice on where to turn? Thanks! Edited by lauren_etherington, 04 September 2014 - 10:36 AM. Hello guys, I am trying my best to upload images to Twitpic by using PHP and OAuth (PECL extension) and I keep getting "Could not authenticate you (header rejected by twitter)". Can someone tell me what am I doing wrong? This is my code so far: $arguments[] = "oauth_consumer_key=" . $this->consumer_key; $arguments[] = "oauth_nonce=" . md5(time()); $arguments[] = "oauth_signature_method=HMAC-SHA1"; $arguments[] = "oauth_timestamp=" . time(); $arguments[] = "oauth_token=" . $this->oauth_token; $arguments[] = "oauth_version=1.0"; $sbs = oauth_get_sbs("POST", "http://api.twitpic.com/2/upload.xml", $arguments); $signature = urlencode(base64_encode(hash_hmac("sha1", $sbs, $this->consumer_secret . "&", true))); $arguments[] = "oauth_signature=" . $signature; sort($arguments); $headers[] = "X-Auth-Service-Provider: http://api.twitter.com/1/account/verify_credentials.json"; $headers[] = "X-Verify-Credentials-Authorization: OAuth\n" . implode(",\n", $arguments); $postfields["key"] = $this->api_key; $postfields["media"] = "@$image"; $postfields["message"] = $message; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, "http://api.twitpic.com/2/upload.xml"); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl, CURLOPT_VERBOSE, true); curl_setopt($curl, CURLOPT_HEADER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); echo curl_exec($curl); Kind regards and thanks in advance. Hi, I'm trying to integrate my web based application with facebook. First of all, I created page login/facebook which redirects user to the URL: Code: [Select] https://www.facebook.com/dialog/oauth?client_id=MY_ID&redirect_uri=https://www.domain.com/connect/facebook&scope=email,user_about_me,user_location So far so good. Have no problems at this stage. If user authorize my application, he gets redirected to the www.domain.com/connect/facebook page. On this page I create user in my database using data returned by FB or just authorize user and create session. On this step I have issues. When I use code from the examples from Facebook Developers Help Page everything works: Code: [Select] $token_url = "https://graph.facebook.com/oauth/access_token?client_id=" . $this->app_id . "&redirect_uri=" . urlencode($my_url) . "&client_secret=" . $this->secret . "&code=" . $code; $access_token = file_get_contents($token_url); $graph_url = "https://graph.facebook.com/me?" . $access_token; $user_object = json_decode(file_get_contents($graph_url)); When I use following snippet everything works perfectly. However I prefer to use PHP-SDK and having problems. When I use following snippet: Code: [Select] $session = $this->facebook->getSession(); var_dump($session); if( $session ) { try { $uid = $this->facebook->getUser(); $me = $this->facebook->api('/me'); var_dump('me'); } catch (FacebookApiException $e) { error_log($e); } }session is null. After having some fun with PHP-SDK I noticed some funny stuff: When I use SDK getLoginUrl() method to generate redirect URL, it seems to be partially working. Code: [Select] $login_url = $this->facebook->getLoginUrl( array( 'api_key' => $this->api_key, 'req_perms' => 'email,user_work_history,user_about_me,user_location', 'next' => 'https://www.domain.com/connect/facebook' ) ); Now when users authorizes my app, he's being redirected to correct page with some params, URL looks like: Code: [Select] https://www.domain.com/connect/facebook?session={"session_key"%3A"11111111111-111111111"%2C"uid"%3A"11111111"%2C"expires"%3A0%2C"secret"%3A"111111111"%2C"base_domain"%3A"domain.com"%2C"access_token"%3A"1111111|222222.0-33333|sdvsdvsdvsdvsdv"%2C"sig"%3A"gsdbsdbsdbsdbsdbsdbsdb"} Anyone has any idea why it's not hashes or it shouldn't? Or should I leave php-sdk and use the way with file_get_contents()? Been fighting with this for awhile. Finally needed to seek advice. I have a URL setup to go to facebook and get information. It's just a standard link... Code: [Select] a href="https://www.facebook.com/dialog/oauth?client_id=CLIENTIDHERE&redirect_uri=http://www.website.com/facebook_connect.php?response_type=token">Facebook Connect</a></p> That ends up sending them back to my receiver script. I have it laid out as follows: Code: [Select] <?php /* Facebook OAuth Procedures */ $app_id = APPIDHERE; $app_secret = SECRETKEYHERE; $code = $_REQUEST["code"]; $url = 'https://graph.facebook.com/me?access_token=' . $code; $user = json_decode(file_get_contents($url)); echo("Hello " . $user->name); ?> That should be very simple. The link takes them to facebook. This part works. If they are logged in and have approved it, it then takes them to my receiver URL. If they are not logged in, it prompts for login, or if they decline and then it takes them to a failure page at that point. So all of that works. Now this receiver page also receives the code back from the previous URL. That all works fine. However, when I try to get to the graph to get the user data, it returns "File Get Contents" and a bad request message. That doesn't make any sense. According to the Facebook API Documentation this is suppose to be how you get the data back. But in this situation I don't even need there name. The only data I need is the Facebook userid so I can match that up with my database and find a connection, then log them into my system. Any advice on why this is not working? I try to modify a twitter application, but I have no idea what I'm doing, this is my code so far: require 'Zend/Oauth/Consumer.php'; $token = unserialize($usersClass->twitterToken()); if(!empty($token)) { $client = $token->getHttpClient($config); $client->setUri('http://twitter.com/users/profile_image/twitter.json'); $client->setParameterGet('screen_name', $screen_name); $client->setMethod(Zend_Http_Client::GET); $response = $client->request(); } I want to get the twitter profile image, but I think it's too difficult for me... This is the code im using to try to connect Empire Avenue API but i must be missing somthing here still trying to figure out all this Oauth stuff.
<?php ?> <html> <head>Empire Traider2</head> <body> <form method="post" action="https://www.empireavenue.com/profile/developer/authorize?client_id=app_543abbac2ad99&response_type=code&state=request_access_token"> <input type="submit" value="Login" /> </form> </body> </html>Oauth.php <?php require('client.php'); require('GrantType/IGrantType.php'); require('GrantType/AuthorizationCode.php'); const CLIENT_ID = 'app_543abbac2ad99'; const CLIENT_SECRET = '1ee4b7f5d702d2c7e64523daf4d107b3dd82a0a787f117986d84f'; const REDIRECT_URI = 'https://yousearch.mobi/OAuth2/oauth.php'; const AUTHORIZATION_ENDPOINT = 'http://www.empireavenue.com/profile/developer/authorize'; const TOKEN_ENDPOINT = 'https://api.empireavenue.com/oauth/token'; $client = new OAuth2\Client(CLIENT_ID, CLIENT_SECRET); if (!isset($_GET['code'])) { $auth_url = $client->getAuthenticationUrl(AUTHORIZATION_ENDPOINT, REDIRECT_URI); header('Location: ' . $auth_url); die('Redirect'); } else { $params = array('code' => $_GET['code'], 'redirect_uri' => REDIRECT_URI); $response = $client->getAccessToken(TOKEN_ENDPOINT, 'authorization_code', $params); parse_str($response['result'], $info); $client->setAccessToken($info['access_token']); $response = $client->fetch('https://api.empireavenue.com/profile/info'); echo $response; echo 'test'; } ?>Here are the docs http://www.empireave...elopers/apidocs Can someone please help me in setting up OAuth server and client implementation in PHP? Even after lots of googling I could only find very basic and raw examples which are very difficult to understand. Thanks in advance.
My script has 3 classes (that are relevant to this discussion): DB, User and Validate. They are all in independent files and loaded automatically, when required, by an autoloader.
The error messages I am getting a Any pointers as to what I am doing wrong, or what I should be doing, would be most welcome. I am currently doing the following but wish to change to using JWTs. A webserver is running some CRM system which has its own authentication system and browsers can access public routes without logging and but must log on first to access private routes. All the routes on the webserver which are prefixed by "api" will be forwarded to specific REST API along with an "account" GUID in the header and the user's ID if it exists. For the routes that require a user to be logged in, the webserver will first check if a session exists, and if not make a preliminary GET request to the REST API which includes the GUID as well as the user's ID and encrypted password (both based on the webserver's CRM DB) in the URL. Not sure whether anything is possible by including the hashed password and am currently not doing anything with it. The REST API queries the DB using the GUID and webserver's user ID and returns the REST API's users ID and the webserver stores it in a session. The REST API receives the GUID and potentially the REST API's user ID and queries the DB to retrieve the account and potentially user before executing the route, and returns the response to the webserver which it returns it to the browser.The new approach might be something like the following: Before the webserver forwards any request to the REST API, it checks if a session is set, and if not performs a GET request to the REST API along with the GUID and if known user's credentials in the URL and receives a JWT which contains a payload including the account PK, and potentially the user PK, user's access level, etc. All future requests include this JWT in the header. The REST API no longer queries the DB to get the account ID and user authorized settings as it is provided in the JWT.A couple of questions: What should be done if a non-logged on user first accesses a public route, gets a JWT, and stores it in a session, but then later logs on and accesses a private route? The webserver thinks it has a valid JWT and will send it but the REST API will then decrypt it and find there is no user it. One option is for the webserver to use two sessions, but this sounds kludgy. Or maybe the REST API returns some header which instructs the webserver to re-authenticate, but not sure if even an option, and if so how to cleanly prevent some loop. Also, would it be necessary to issue a new JWT or can the payload in a JWT be changed? Is GET appropriate for requesting the JWT's or should I use some other method? Is it appropriate to include the user's access level in the JWT payload? Will one need to wait until the JWT has expired before their access level changes? Any ideas how to deal with using the user's password on the CRM to also authenticate on the REST API? The GUID is probably secret enough for the application and if an issue, can just use the GUID and username. Am I going down an reasonable path and anything else obvious I should be considering?Thanks! Hi all, I have an authentication part on my website that checks every page through a session variable if a user is logged in and which user it is. When I test my code on my computer it works perfectly registration and login goes smooth but when someone on another computer tries it they get the acces denied page.... does anyone know why??? Greets Ryflex Hello everyone, I have a site where users sign up using an email address as their username. I want to be able to verify that their email address is valid without having to send them a confirmation email that they have to click some link in before they are allowed to sign in to the website. Maybe something that pings the email server for a specific address, and if the address is not valid, alert the user to enter a valid address. Does anyone have any ideas or information that you could point me to to assist me with this task? Thanks in advance for any help or ideas. Pardon my noobness, but I'm learning to wrap AJAX into my work and use it to get XML instead of "static" PHP that generates the HTML. The login/security portion has my head spinning, but it's probably not as difficult as I think and I'm probably just confusing myself. In the past, for each PHP page in my site, I would perform a quick salted login check based on the username/password stored in the $_SESSION variables. Perhaps it was a bit overboard to check on each page, but, well, I did it. With AJAX, I *NEED* to ensure that the php resulting from an AJAX POST request won't run if the user isn't authenticated, and I need to ensure that they didn't just somehow force a $_SESSION variable to reflect an authenticated session. I also need to ensure that someone can't just load up the PHP page on it's own, somehow send a POST to it and run it without being authenticated. I suppose that beyond the larger picture of "How do I ensure that the user is authenticated, the POST request is authentic, and nobody has forced a change in the $_SESSION stored on the server, I have a few specific questions. I know that in part I'm confused about the whole cookie/SESSION process. In my old PHP site, the SESSION number was stored on the cookie on the user's machine. If the info is sent via AJAX, does the PHP get the SESSION info from the cookie or does it have to be explicitly sent? With potentially several users sending AJAX requests at the same time, how will my PHP know which SESSION to use for each request? Is is secure enough to set an "Autheticated" flag in $_SESSION once the user is authenticated the first time? Is it really just as simple as sending a username/salted password hash as AJAX/POST and setting an authenticated flag in the SESSION to ensure that the rest of the AJAX application runs without allowing someone to back-door the PHP? Hi, iam working on a curl based authentication and iam sending a curl request to one of my pages, like this: <?php $ch = curl_init("http://localhost/test.php"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($curl, CURLOPT_USERPWD, 'myuser:mypwd'); // sending username and pwd. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($curl, CURLOPT_USERAGENT, 'Sample Code'); curl_setopt($curl, CURLINFO_HEADER_OUT, true); $output = curl_exec($ch); print_r(curl_getinfo($ch)); curl_close($ch); echo '<br><br>'; echo $output; ?> But in my test.php page, iam not able to get the username and password values, in $_SERVER array. What could be the problem? I have had a problem with people attacking my site and trying to gain access to users accounts so i beefed up security, however now users are complaining they keep getting logged out. Here are the variables i use to validate the users and i dont want to strip them down any more can anyone give me any ideas for changing them so its still secure but not so strict as to keep logging the users out? 1. Username & password is encrypted into a cookie and verified on every page they visit. 2. There ip address is recorded on login and is checked against there current ip, on every page they visit via MySql. 3. When the user logs in a unix time stamp (mySql) is generated an updated of every page they visit and if it has not been updated in the last 60 mins the user is logged out. 4.I also generate a random key which is stored in the DB and is passed on every page via GET. 5.If a user tries to login and fails an email is sent to them and if 3 unsuccessful attempts user is locked out for 30mins. Okay, at the moment, when a user logs into my website a token is created. The token is made from a random code, their name and their email. This token is then stored next to their name in the DB. If the user chooses to be remembered, the token is stored as a cookie, otherwise it's stored as a session var. Every time a page is loaded, a comparison is made between the DB token and the session/cookie token to authenticate. HOWEVER, this does not work if the user decides to login from different locations/ip addresses. How would I go about allowing this? Could I created a table and then store the IP address and the token for that IP address? |