OAuth2 in 8 Steps


What you'll be learning

NOTE: The code in this tutorial is now out-of-date, however the fundamental concepts of OAuth that we teach are still 100% valid.

OAuth2: that mystical beast that you kind of understand and occasionally wrestle to integrate with some social media site.

Time to master OAuth2... and why not do it by building a real app with farmers, chickens and real-life providers like Facebook and Google Plus. We'll show you how OAuth really works while looking at how OAuth will feel by using SDK's and other tools that give you shortcuts.

And like always, we'll go directly at the ugly details, like token expiration and having a user deny access to your application. Here's what you'll be learning:

  • 3 main OAuth grant types: client credentials, authorization code and implicit;
  • The exact flow behind getting your application authorized, exchanging an authorization code for a token, and using the token;
  • Authentication (single sign-on) using OAuth;
  • Handling expired tokens;
  • Using refresh tokens;
  • Integrating and authentication with Facebook;
  • OAuth integration with Google+;
  • What to look out for with security and how you can tighten things.

Your Guides

Brent Shaffer Ryan Weaver Leanna Pelham

Buy Access

Questions? Conversation?

  • 2019-11-12 Victor Bocharsky

    Hey Axel,

    This course is all about OAuth2 and how to use it. If you're looking for restful API, you can take a look at other specific courses we have, see courses in this track: https://symfonycasts.com/tr... . I suppose you would need to combine knowledge of a few courses to achive what you're looking for.


  • 2019-11-11 Axel Jeremy

    is this tutorial help to build restful api witth auth2?

  • 2019-11-07 weaverryan

    Hey Kevin Smith!

    This is on our idea list, but nowhere on our schedule. Unless there is a sudden big push for it from many people, I don't expect it in the next 6 months. Sorry I can't be more helpful - we have big backlog of nice topics to get to - never enough time!


  • 2019-11-06 Kevin Smith

    Any news on a SAML course?

  • 2019-08-08 jonlai

    I second this. A SAML course would be nice as well.

  • 2019-07-15 Diego Aguiar

    TEST comment

  • 2019-01-29 Victor Bocharsky

    Hey Michael,

    First of all, this course is still relevant. But this course is a bit specific. If you want better to understand the whole process of OAuth - definitely take a look at it. But if you just want to do login/register via some social networks, you can start with HWIOAuthBundle docs or with knpuniversity/oauth2-client-bundle that is more low level but more flexible, so with it you won't need to override things if you want to do something custom in comparison with HWIOAuthBundle. But it depends on your case.

    I hope this helps.


  • 2019-01-27 Tac Tacelosky

    I'm trying to allow users to register and login with Google and Facebook with a Symfony 4.2 application. I've been using FOSUserBundle, but that seems to have fallen out of favor. This tutorial is about 5 years old, is it still relevant, or can you recommend where to start for a "Best Practices" on this? https://github.com/hwi/HWIO...


  • 2018-03-21 weaverryan

    Hey Ahammad Karim!

    Do you have some specific questions about OpenID Connect? It's based on OAuth, so the flow is the same that you see here. This is a nice article describing it a bit: https://auth0.com/docs/prot.... As far as I understand, the big difference is that it formalizes how you get user information: when you get your access token, you can *also* get an "ID token", which is a JSON web token (JWT) that, when decoded, contains user information. This is slightly different than what we were doing in this tutorial, where we would (A) get the access token and then (B) use it to make an API request for user information. With OpenID Connect, you get all of the information you need with step (A). I'm far from an expert on it, but this is my impression ;).


  • 2018-03-20 Ahammad Karim

    What about implementing OpenID Connect?

  • 2017-12-28 Victor Bocharsky

    Hey Tom,

    Last update of this tutorial was on Feb 23, see the latest commit: https://github.com/knpunive... - but this date shows when the course script were updated, unfortunately we do not track videos updates.


  • 2017-12-07 Tom Cider

    When was this video last updated?

  • 2017-04-17 weaverryan

    Hey Tummala Anvesh!

    We don't have a tutorial about how we built the "Coop" app. But, I can tell you a bit about it and show you the code :). And btw, we do have a few rest courses - http://knpuniversity.com/sc... uses Silex and http://knpuniversity.com/sc... uses Symfony.

    First, the Coop app can be found here: https://github.com/knpunive.... It was never meant to be a teaching tool - more just to exist to help out with this tutorial. Its code is also getting a little bit old - it's based on an older version of Silex :). Inside, we use the OAuth server library created by our co-author (and all around nice guy) Brent: https://github.com/bshaffer....

    I hope that helps!

  • 2017-04-14 Tummala Anvesh

    If you already created a course for the Rest API endpoint's implementation for the ones that are listed in this course, please provide the link. Thanks in Advance.

  • 2017-01-04 weaverryan

    Thanks Ramon! No current plans, but it's a good idea - I've added it to our list! But, sadly, we have a lot of other screencasts that would probably come before it.


  • 2017-01-03 Ramon Felipe

    Great course! Any plans for a SAML course? Thanks.

  • 2016-09-12 Victor Bocharsky

    You're welcome! This's a good choice for your project ;)

  • 2016-09-12 Robert

    Hey Victor

    As always you're first to help :) Thanks man! :)

  • 2016-09-12 Victor Bocharsky

    Hey Rober,

    Sure! The OAuth2 protocol is supported by many social networks for now, e.g. Facebook, Google, Instagram, etc. So this's still a good course to learn.


  • 2016-09-09 Robert


    Is this still good to learn ?

  • 2016-04-01 weaverryan

    Hi Andre!

    We're going to work on a feature for this - enough people are asking, and yes, you should be able to celebrate accomplishments! If you need to show your employer some proof before we are able to release this feature, you can contact us and we can make something available to you :).


  • 2016-03-30 Andre

    Thank you for the reply. I would have something like codescool, something like that - https://www.codeschool.com/...

    Is it possible to do a page where my employer would see that I viewed a course?

  • 2016-03-29 weaverryan

    Hey Andre!

    We don't have any certificates currently, but it *is* something we're considering. What would you like the certificate for? Is it for a current employer? Or something you'd like to include in a resume for future work?


  • 2016-03-25 Andre

    Hello, I bought account in knp, and I'm learning your courses. Can I get certificate after finish a course? Best regards, Andre!

  • 2016-01-19 weaverryan

    Hi Gary!

    There is no certification (at this time) at the end of the course. You will know a ton about OAuth, but there's no official certification that we offer.


  • 2016-01-18 Gary

    Does this course come with any certification at the end?

  • 2015-07-07 老胖子-何必都


  • 2015-06-09 weaverryan

    Thanks Josh! We're aware and it's on our list to update. Until then, the course is still teaching all the right stuff, but the code examples using Guzzle (if you're coding along) will need to be updated.


  • 2015-05-19 weaverryan

    Hey Abhishek!

    While we don't talk about how to implement the "server" side of OAuth, that code *is* available in the code download or at https://github.com/knpunive....


  • 2015-05-19 Abhishek Panda

    Does this course gives the whole code of http://coop.apps.knpunivers...

  • 2014-09-08 weaverryan

    Hi Akshar!

    Both the "authorization code grant type" (https://knpuniversity.com/s... and the "Implicit grant type" (https://knpuniversity.com/s... are examples of strategies that allow you to authorize without exposing your application's secret key :). Which you choose depends on your requirements, but both work fine (though the authorization code is arguably a little bit more secure).

    I hope that helps!

  • 2014-09-08 Akshar

    Hi, in the last tutorial that it is not a good practice to expose client secret when we put code on web and that subsequent tutorials explain how to over come this, but i could not find an explanation for the same, could you please tell me if i am missing anything, thanks.

  • 2014-09-03 weaverryan

    Hey Will!

    This is framework-agnostic, though we *do* use Silex to illustrate things. Fortunately, Silex will feel very similar to Laravel, and both use Symfony under-the-hood. So yes, this will work for you, and you'll probably be able to leverage some additional Laravel-specific libraries to make your life easier.


  • 2014-09-02 Big Will

    Does this tutorial rely on knowing how to use the Symphony framework or is framework agnostic? Can I apply same to a say, a Laravel app?

  • 2014-08-25 Niket Sharma

    thanks ryan for the tutorial, this helped me a lot.

  • 2014-08-25 weaverryan

    Hey there!

    Glad you're going through it! I think you're missing just one small thing. In the version of Guzzle we're using, you need to call send() after calling post(). send() is what actually gives you the response - without it, you're printing out the request. Try adding send() and see if it works.

    Good luck!

  • 2014-08-25 martinc

    Did the tutorial, its great thanks! Created an account, added an App and obtained the secret but now
    I am having problems with getting a dynamic token. My code below:

    $client_secret = 'bcd815114ff04be2f4669ae599a47158';
    $clientID = 'App2';

    // Create a client with a base URL
    $client = new GuzzleHttp\Client(['base_url' => 'http://coop.apps.knpunivers...']);

    $dyntoken = $client->post('/token', [
    'body' => [
    'client_id' => $clientID,
    'client_secret' => $client_secret,
    'grant_type' => 'client_credentials',

    $responseBody = $dyntoken->getBody(true);

    class GuzzleHttp\Stream\Stream#27 (6) {
    private $stream =>
    resource(63) of type (stream)
    private $size =>
    private $seekable =>
    private $readable =>
    private $writable =>
    private $uri =>
    string(10) "php://temp"

    Why am I getting this? Is there something wrong with my post construction?

  • 2014-08-21 weaverryan

    Thanks Niket! I've opened up an issue about this: https://github.com/knpunive...

    And I'm really glad you're enjoying the tutorial :)


  • 2014-08-21 weaverryan

    Hey Niket!

    Unfortunately, I can't say how this is done in Java :). You could of course do it manually by building an array and then manually turning that into the correct string, but there's probably a better way.


  • 2014-08-20 Niket Sharma

    tutorial is good, i am learning this so i thought i should inform this issue. thanks

  • 2014-08-20 Niket Sharma

    there is a problem in the data if i use any old token it will give the same scope with was used to generate token. if i give the scope egg count only and then i generate the token it will work correctly but if i use the old token which i used to collect eggs, is still active and working, the token should expire when the scope is changed.

  • 2014-08-19 Niket Sharma

    // src/OAuth2Demo/Client/Controllers/CoopOAuthController.php
    // ...

    public function redirectToAuthorization(Request $request)
    $url = 'http://coop.apps.knpunivers...
    'response_type' => 'code',
    'client_id' => '?',
    'redirect_uri' => '?',
    'scope' => 'eggs-count profile'

    How can i implement this http_build_query in java??

  • 2014-08-15 weaverryan

    Hi Roman!

    Yes, you're absolutely right. When we use the "client credentials" grant type, it's really limited. Our final access token only has access to do things to our application (or often, the user that created the application). When we use the authorization code to get the access token, it does 3 things:

    1) It tells the server which user we want permission to "act as" (because the server keeps track of which authorization code is for which user)
    2) It tells the server which scopes (i.e. permissions) the user has approved for us to have
    3) It proves that the user has actually authorized us to have these privileges (since we couldn't easily guess a valid authorization code, and they have a really short lifetime).

    So again, you figured it out! Hopefully these details help even more.

    Cheers and thanks for the great question!

  • 2014-08-15 RomanArkharov

    Oh, I think I've understood. By using authorization code we can get access to any account on remote server, otherwise we can access only to own account. Am I right?

  • 2014-08-15 RomanArkharov

    Hello, my name is Roman.

    Could you please explain me. Why do we need to request authorization code to get access token? In such way we have two steps:
    * on first step we send client id to server and get authorization code from server,
    * on second step we send authorization code from previous step, client id and client secret and get access token.

    But in previous lesson we just requested access token by using only client id and client secret without authorization code.

  • 2014-04-30 weaverryan

    Hi there!

    The "Download" button only shows up if you own the course, even for the free chapters - that's our bad (it's on our bug tracker). However, you can download the starting code directly from GitHub - it's exactly the same as the code download :) https://github.com/knpunive...


  • 2014-04-29 Jim Fisher

    No one seems to have pointed out that despite this page saying "Click the Download button on this page to get the starting point of the project," there is in fact no "Download" button anywhere on the page.

  • 2014-04-28 weaverryan

    We're working on it hard this week and hoping to get it out ASAP! However, the first episode won't contain anything about OAuth - but we'll have that for episode 2!


  • 2014-04-23 Sergio

    Hello Guys, nice course! Does have any ETA for REST ?

  • 2014-03-31 weaverryan

    Not on purpose! :) Thanks for letting me know - the text for the chapter is back now!


  • 2014-03-29 Paul

    So you actually removed the text contents of this chapter ???

  • 2014-03-24 Alysson Bortoli

    Thanks weaverryan, appreciate it!

  • 2014-03-24 weaverryan

    Alysson Bortoli It's been on my list to change that about our comments - I think it confuses everyone. But yea, we totally could see that the video wasn't playing - something must've gone wrong on uploading. We've re-encoded it and it works fine now. Thanks so much for pinging us on this!


  • 2014-03-20 Alysson Bortoli

    Sorry weaverryan, I thought comments were page related, or at least video related. The "/refresh-token" is not playing for me in Safari 7.0.2 (9537.74.9) or Google Chrome 33.0.1750.152, Firefox plays fine, so I assume is file format related. Cheers

  • 2014-03-20 weaverryan

    Hey Alysson Bortoli!

    It looks like it's working for me :). Is the video not playing on a particular chapter or all chapters? If you change browsers, does that help? And if so, what's the offending browser?


  • 2014-03-19 Alysson Bortoli

    Hey guys, this video is not working :/

  • 2014-03-19 Thorsten Drönner

    Looks good to me. Maybe some scoop checking additionally.

  • 2014-03-18 Brent Shaffer

    We've talked about doing a short screencast to cover JWT-Bearer and JWT tokens in general, covering the basics, as well as the different values that can be populated in the JWT header. In addition, we've discussed doing a short screencast on OpenID Connect. What other specifics would you like to see in a screencast like this?

  • 2014-02-24 Thorsten Drönner

    That would be great. I'm currently using oauth in combination with apigility (http://apigility.org). Since th API is mostly used for inter-machine communication (iOS, Android, Web) the clients will get rsa 2048 certificates.

  • 2014-02-17 weaverryan

    Hey @Thorsten!

    JwtBearer isn't included in the tutorial currently. We thought about it - and Brent has actually worked with it a bunch - but decided not to include it originally. But now, we may consider adding it as a blog post or a small tutorial :).


  • 2014-02-14 Thorsten

    How about JwtBearer?

  • 2014-02-10 weaverryan

    Hey @john! Yes, look for them as early as tomorrow actually :)

  • 2014-02-10 John

    Hi! Are the "using refresh tokens" and "tightening up security" parts going to be available soon?

  • 2014-02-04 Nazim

    For those working on windows / xampp, the following would be helpful if you run into sqlite db creation error from the downloaded files (client\data\rebulid_db.php - line 19)


    I had to remove the slash '/' after the colon ':' which ended up being...

    $db = new PDO(sprintf('sqlite:%s', $dbfile));

  • 2014-01-26 weaverryan

    Aw, thanks Anthony :). We'll get everything up for you by Feb 1, with updates through the week.


  • 2014-01-26 Anthony T.

    Hi, great tutorial. Any update on when the rest of the vids will be up?

  • 2014-01-23 weaverryan

    Enjoy - cheers :)

  • 2014-01-23 Michal Szymczak

    At last available, excellent! Great topic selection, as always. Looking forward to it :)

  • 2014-01-10 weaverryan

    We're about to start recording, so we should start releasing parts during the next 2 weeks :).

  • 2014-01-10 Michal Szymczak

    Hi, do you have any estimates when this tutorial will be available?

  • 2013-12-12 Aliaksandr Harbunou

    Yeah, it was a deal for me to connect authorization with Google+ and Facebook. Would be useful.

  • 2013-10-25 Hasin Hayder

    Sweeet! Waiting for this for a long time guys!