This course is archived!
The concepts of OAuth2 we're teaching in this tutorial are still valid, but the course project code is ancient.
03.
Authorization Code Grant Type
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
34 Comments
in /home/spyros/work/p3/start/client/src/OAuth2Demo/Client/Storage/Connection.php line 79
at PDOStatement->execute(array('email' => 'spyrostsiko@punct.ro', 'password' => '9P6NWcis9oBCRdfgZgu/ARRAmP6929RHZbvAxRiUNpThyEJny9kR57O2VDDRKufCGPuNLPoUeE2g+tbIcQBbGg==', 'firstName' => 'Spyors', 'lastName' => 'Tsiko', 'coopUserId' => null, 'coopAccessToken' => null, 'coopAccessExpiresAt' => '', 'coopRefreshToken' => null, 'facebookUserId' => null)) in /home/spyros/work/p3/start/client/src/OAuth2Demo/Client/Storage/Connection.php line 79
at Connection->saveUser(object(User), true) in /home/spyros/work/p3/start/client/src/OAuth2Demo/Client/Storage/Connection.php line 99
at Connection->createUser('spyrostsiko@punct.ro', '9P6NWcis9oBCRdfgZgu/ARRAmP6929RHZbvAxRiUNpThyEJny9kR57O2VDDRKufCGPuNLPoUeE2g+tbIcQBbGg==', 'Spyors', 'Tsiko') in /home/spyros/work/p3/start/client/src/OAuth2Demo/Client/Controllers/UserManagement.php line 58
at UserManagement->registerHandle(object(Application), object(Request))
at call_user_func_array(array(object(UserManagement), 'registerHandle'), array(object(Application), object(Request))) in /home/spyros/work/p3/start/client/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php line 126
at HttpKernel->handleRaw(object(Request), '1') in /home/spyros/work/p3/start/client/vendor/symfony/http-kernel/Symfony/Component/HttpKernel/HttpKernel.php line 66
at HttpKernel->handle(object(Request), '1', true) in /home/spyros/work/p3/start/client/vendor/silex/silex/src/Silex/Application.php line 516
at Application->handle(object(Request)) in /home/spyros/work/p3/start/client/vendor/silex/silex/src/Silex/Application.php line 493
at Application->run(object(Request)) in /home/spyros/work/p3/start/client/web/index.php line 27
i got this error why this happend when i register ?
I didnt change anything from that script.
Hey Spiro Ciko!
Sorry for the slow reply! For some reason, your comment ended up in the Disqus Spam :(.
I this the entire error? It looks like some sort of MySQL error, but I don't actually see the error. It's possible that some of the columns that are being set to null are required, but I'm not sure! If you have a screenshot of the error, that would be perfect :).
Cheers!
Not sure why, but I had to edit 2 files in vendor to make the server not to err for the authorization request:
In both cases the author counted uncountable things...
Hi IvanPuntiy
Sorry about that! Hmm, it works for us, though we do see a warning in PHP 7.2. We're going to leave code as is for now, to see if anyone else has any issues.
Cheers!
What is the reason the scoped Symfony HTTP Client discards 'auth_bearer' options? I created scoped client with 'base_uri' 'http://coop.apps.symfonycas...'. Then added 'auth_bearer' option with `access_token` while calling '/api/me' endpoint. Some debugging shows that 'auth_bearer' options consumed by HTTP Client but Wireshark displays no 'Authorization' header in the actual request. What is the explanation of this phenomena?
Hey erop!
Your'e asking specifically about this behavior in the Symfony HTTP Client? https://symfony.com/doc/current/http_client.html
If so, I'm not sure! I'm not aware of this, nor do I see any reasons why it should be working this way. Using
auth_bearerspecifically when creating a scoped token is allowed - https://symfony.com/doc/current/http_client.html#authentication - and even if you don't configure that, then pass it in when actually making the request, I can't think of any reason why that would happen. If you're pretty sure of this behavior, I'd open up an issue about it - that doesn't seem right to me.Sorry I can't say more!
Cheers!
Is coop still be working in 2020? I am going out of my mind trying to follow this tutorial and i am doing it using the new HttpClient and I cant get it to work and I am starting to wonder if the issue is with Coop (no idea if its still maintained) because i started getting some weird 400 errors too. I have this and it keeps telling me i need an access token (but if i post to pick eggs that works fine):
` $httpClient = HttpClient::create();
`
I always get string(75) "{"error":"access_denied","error_description":"an access token is required"}"
I checked all the permission boxes on coop for this app to rule that out. I do get a token from the /token and am passing it with Bearer.
EDIT: i just tried with the latest guzzle and still its telling me "access token is required"
`var_dump($accessToken);
Hey Michael L.
Can you try to change uri of COOP app to http://coop.apps.symfonycas... I guess it can work not stable due to redirect to the new domain, however it should work. If it doesn't help let me know here and we'll try to investigate it.
Cheers!
I would suggest putting a notice on the start of the tutorial that you must use the new URL so others dont go crazy like I did....
Yep Thanks for suggestion, I think it will be really great!!!
Cheers!
YES! it works! OMG I was tearing my hair out because for some reason the POST's all work fine with the redirect but the GET's didnt.
Hey Folks thanks for this tutorial!
I've seen the composer get broken by version incompatibility while versions climbs higher... The easiest way around this, is to go fix the version numbers.
In composer.json adjust every version according to this pattern: "1.2.3"
So remove every "~"-sign and if the the version is composed out of two parts (major and minor), then add a third part (the build) ".0" to it. So for example you get from "~1.5" to "1.5.0".
Safe the file, do 'composer update' and your good to go.
I had to add downgrade to Symfony2 by adding the following line:
`
"require": {
`
to <b>client/composer.json</b> in order to follow this tutorial. Otherwise you'll get errors due to deprecation and removal errors.
Thanks Vladimir Z.! And yep, the content of this tutorial is holding strong... but some of the tools that we used are aging. If you use download the "start" course code, it all should work - that uses all the original versions of the libraries. For the most part, those tools are really secondary to what we're learning anyways.
But, btw, if anyone has any issues, definitely let us know :).
Cheers!
Hi,
I can find the download button
Hey Saad!
Right now, the download button doesn't show up unless you own this screencast (or have the all-access pass). I want to fix that, but for now, you can also get the starting state of the project right form GitHub: https://github.com/knpunive...
Cheers!
I'm running nginx, and have created the conf file for this 'client' site, I'm using a port rather than socket for php-fpm in nginx conf file for 'client' site i.e. 127.0.0.1:9000, and added it server name to local hosts file.
I get the home page but all the css & js not found, i.e. {{ app.request.basePath }}/css/bootstrap.css }} doesn't resolve properly.
I've done the composer install, is there anything else I'm missing?
PS - I'm using the Silex conf setup for nginx as provided on Silex setup page
Hey Todd,
Could you debug what is your "app.request.basePath" path is? Is it a path to web/ directory where your index.php is? Do you configure web/ folder as a document root in Nginx config? Are you sure that bootstrap.css file exists in path/to/web/css/bootstrap.css? Can you access any other files in document root except index.php? Also, could you get a page other than homepage? Does it works the same way?
Cheers!
Hey Victor,
I've tried debugging 'app.request.basePath', yes this is the cause of the problem, as it returns empty.
My document root for it's nginx config points to the web/ folder. All the bootstrap css & js files reside in the correct path.
I can navigate to other pages such as login & register etc..but css & js path's don't get resolved.
Cheers.
Hey Todd,
Good debugging! So there're 2 possible good ways I think:
- Start using asset() Twig function: https://silex.sensiolabs.or...
- Or you can cheat a bit with homepage URL, for example: "{{ path('homepage') }}/css/bootstrap.css", where homepage route always is a correct address of the web/ folder, so you just need to add the path to assets *relative* to the web/.
Cheers!
If you are getting a pdodriver not found exception you may have to install sqlite and php5-sqlite. I am running on vagrant box ubuntu 14.04.
Here are the commands if you are ubuntu flavored linux
sudo apt-get install sqlite
sudo apt-get install php5-sqlite
In <strong>server/composer.json</strong> I see the following two components
<br />"require": {<br />...<br />"bshaffer/oauth2-server-php": "dev-develop",<br />"bshaffer/oauth2-server-httpfoundation-bridge": "dev-master",<br />...<br />}<br />I need to implement an OAuth2 server. Would you recommend to use these libraries for my purposes, or are there better alternatives. I'm not done with this course and haven't done much research yet, that's why I wanted to ask your suggestion.
Thanks,
Hey Vlad,
Yes, you can use it for sure - they are pretty stable now. Btw, those libs are from a guy who works at Google ;) There's another one cool lib I could advice you: https://github.com/thephple... . However, if you want to match our screencasts - bshaffer's libs are a good choice I think.
Cheers!
In the "Authorization Code Grant Type" video, where we are "Exchanging the Authorization Code for an Access Token",
I can't get the $responseBody to var_dump in the receiveAuthorizationCode() function (copied below). Instead of the expected $responseBody, I see the "Hello World" string that my redirect_uri file /web/handle.php prints out.
Because I couldn't get the following code to work on my test site:
I hard-coded my redirect_uri like so:
Could that be why my receiveAuthorizationCode() isn't working?
And, in any case, how could the receiveAuthorizationCode() even run if COOP is redirecting to /web/handle.php and the function that needs to fire is inside /src/OAuth2Demo/Client/Controllers/CoopOAuthController.php?
What have I done wrong?
Also, I'm wondering if I need to replace this line with more standard PHP since the course says that that function is customized for the tutorial's app. (although I'm not sure what standard PHP redirect code is).
Thanks in advance for your help.
Hey Debra,
First of all, do you use Silex framework as we do in this screencast? If no, then generateUrl() won't work until you create it. But if you use Silex as we, let's fix the problem with this generateUrl(), but I need to know what exactly error do you have with it to help you fix it.
About hard-coded the redirect_uri - no problem, I don't think the problem in it, of course, if you hard-coded the correct URL ;)
<blockquote>
And, in any case, how could the receiveAuthorizationCode() even run if COOP is redirecting to /web/handle.php and the function that needs to fire is inside /src/OAuth2Demo/Client/Controllers/CoopOAuthController.php?
</blockquote>
That's a good question. In shorts, you need a front-controller, an entry point for every request to your application - it's web/index.php file in out case. Then with router system you point a route (a specific URL) to a specific controller, e.g. you set up "receiveAuthorizationCode()" to match the "/coop/oauth/handle" route, so when you go to the"/coop/oauth/handle" URL - the receiveAuthorizationCode() method will be fired up. We configure these routes in "CoopOAuthController::addRotues()". But if you're not using Silex, it's almost pointless for you - you need to implement this in your application somehow. Actually, it's basics of any framework.
What about replacing redirect() with a more standard PHP redirect code, it depends on what framework do you use. If you're on Silex, then you better use this redirect() built-in function. But if you're write withut any framework, of course this redirect() won't work since most probably you don't have this function. Then you need to use native PHP support to make redirects:
But keep in mind it has some conditions, see header() PHP built-in function for more information: http://php.net/manual/en/function.header.php
Cheers!
Question on the course payment ($12). Is that for the entire OAuth course, the complete 8 steps, or just this step? Thanks.
Hey Ramon,
The "OAuth2 in 8 Steps" is just a name! :) So $12 is a price of the whole course, which contains of 11 chapters.
Cheers!
Thanks!
Thank you for the tutorial. I've been staring at the RPC spec docs for 3 weeks and my eyes were sore.
Near the end of video "Authorization Code Grant Type", I first receive the access token and then use that access token to connect to the /api/me endpoint with an "Authorization" header. I get the proper json response including my Coop user_id and then try to save to my local db which fails. I've stepped through the code with Xdebug to verify this and it appears to try and create a new user in the sqlite db instead of updating. My code is below. Thank you for your help:
/coop/start/client/src/OAuth2Demo/Client/Controllers/CoopOAuthController.php
public function receiveAuthorizationCode(Application $app, Request $request)
// ...
$response = $request->send();
$responseBody = $response->getBody(true);
$responseArr = json_decode($responseBody, true);
$accessToken = $responseArr['access_token'];
$expiresIn = $responseArr['expires_in'];
$expiresAt = new \DateTime('+' . $expiresIn . ' seconds');
$request = $http->get('/api/me');
$request->addHeader('Authorization', 'Bearer ' . $accessToken);
$response = $request->send();
$json = json_decode($response->getBody(), true);
$user = $this->getLoggedInUser();
$this->coopAccessToken = $accessToken;
$this->coopUserId = $json['id'];
$this->coopAccessExpiresAt = $expiresAt;
if ($this->saveUser($user)) // This part fails and $json['id'] is not saved
{
echo $response->getBody(); die;
}
die('Save failed');
I figured out what I was doing wrong. I was using $this instead of $user when setting the coopAccessToken, coopUserId, and coopAccessExpiresAt properties. Changing the end of my code to the following worked:
/..
$user = $this->getLoggedInUser();
$user->coopAccessToken = $accessToken;
$user->coopUserId = $json['id'];
$user->coopAccessExpiresAt = $expiresAt;
if ($this->saveUser($user)) // This part fails and $json['id'] is not saved
{
echo $response->getBody(); die;
}
die('Save failed');
Hey Nathan! I'm glad you got it sorted out - I was just looking through your first comment when I saw you had already fixed it. Awesome! Good luck!
very usefull
"Houston: no signs of life"
Start the conversation!