Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PHP] Laravel improvements #462

Open
barryvdh opened this issue Jun 22, 2015 · 14 comments
Open

[PHP] Laravel improvements #462

barryvdh opened this issue Jun 22, 2015 · 14 comments

Comments

@barryvdh
Copy link
Contributor

Thanks for this project! Here are some improvements for Laravel. If you want I can PR them:

  • Instead of using a new Authenticate method and store the user in the request, we could also log the user in directly: $this->auth->onceUsingId($payload['sub']);
    If you create a new middleware (eg. jwt) you can use both the jwt middleware and regular auth middleware. In the controllers, you can just do Auth::check() and Auth::user().
  • Instead of using the custom OAuth for all providers, we can use https://github.com/laravel/socialite which handles Bitbucket, Github, Google, Twitter, LinkedIn and Facebook by default + extra via http://socialiteproviders.github.io/

For OAuth2, it's something like this for every provider:

public function provider(Request $request, $name)
{
    if ($request->has('redirectUri')) {
        config()->set("services.{$name}.redirect", $request->get('redirectUri'));
    }        

    $provider = \Socialite::driver($name);
    $provider->stateless();

    try {
        /** @var AbstractUser $profile */
        $profile = $provider->user();
    } catch (ClientException $e) {
        return response()->json(['message' => (string) $e->getResponse()->getBody()], 500);
    }

    $user->$name = $profile->getId();
    $user->name = $profile->getName();
    $user->avatar = $profile->getAvatar();
    $user->email = $profile->getEmail();
    $user->save();

    return response()->json(['token' => $this->createToken($user)]);
}

OAuth1 is a bit different, but can get the same Profile information:

    $provider = \Socialite::driver($name);

    // Part 1 of 2: Initial request from Satellizer.
    if ( ! $request->input('oauth_token') || ! $request->input('oauth_verifier')) {
        // Redirect to fill the session (without actually redirecting)
        $provider->redirect();

        /** @var TemporaryCredentials $temp */
        $credentials = $request->getSession()->get('oauth.temp');

        return response()->json(['oauth_token' => $credentials->getIdentifier()]);
    }
    // Part 2 of 2: Second request after Authorize app is clicked.
    else
    {
        $credentials = new TemporaryCredentials();
        $credentials->setIdentifier($request->input('oauth_token'));
        $request->getSession()->set('oauth.temp', $credentials);

        try {
            /** @var AbstractUser $profile */
            $profile = $provider->user();
        } catch (ClientException $e) {
            return response()->json(['message' => (string) $e->getResponse()->getBody()], 500);
        }
    }

This will make it a lot simpler to add more drivers :)

Common pitfalls:

@sahat
Copy link
Owner

sahat commented Jun 25, 2015

👍 for the first suggestion. I am not too familiar with Laravel's Authenticate middleware, so I did what I could in order to get the User object after successful authentication.

I don't like the idea of using a 3rd-party library to abstract away all implementation details of oauth providers in this specific case. The only reason I was able to write so many backend examples, when I am only comfortable with Node.js, is because the flow is exactly the same, regardless of which language or server-side framework you are using. Another advantage is that it could be used as a learning resource, because it isn't a black box like passport.js, omniauth, socialite.

There used to be a .htaccess that fixed the CORS problem, but I guess it was nuked during Laravel 4 to Laravel 5 conversion. I'll see if I can revert it back.

@barryvdh
Copy link
Contributor Author

I understand about the 'black box' thing, but isn't that pretty much the same for users using sattelizer? If they wanted to do the whole process manually, they wouldn't need to use sattelizer ;)

@sahat
Copy link
Owner

sahat commented Jun 25, 2015

I see your point. Both arguments are valid, in one case it is explicit and easy to understand, in another case it is short & simple and "don't care how it works,I just want it to work".

I'll think about it, meanwhile I would appreciate that PR for the new Laravel middleware.

@syropian
Copy link

syropian commented Jul 4, 2015

@barryvdh I'd love to see an example of Socialite and JWT playing nice together with something like GitHub authentication.

@barryvdh
Copy link
Contributor Author

barryvdh commented Jul 4, 2015

I'll see if I can put up an example or blog post about it soon :)

@syropian
Copy link

syropian commented Jul 4, 2015

@barryvdh That'd be amazing! Thanks :)

@aligajani
Copy link

@barryvdh Thanks +1, by the way, with this method, Auth::check() or Auth::user() doesn't work. How can I make JWT play nicely with Laravel, and if you can guide us more on the Socialite integration, I'd be grateful :)

@barooney
Copy link

barooney commented Jul 9, 2015

You may have a look at this tutorial, which shows the use of JWTs within Laravel and Angular:
https://scotch.io/tutorials/token-based-authentication-for-angularjs-and-laravel-apps

I forked the repository from @chenkie and added Socialite support to it:
https://github.com/barooney/jot-bot/

Maybe you want to have a look at it, @barryvdh.

@barryvdh
Copy link
Contributor Author

Can you check out http://barryvdh.nl/laravel/lumen/angular/2015/07/19/oauth-in-javascript-apps-with-angular-lumen-using-satellizer-laravel-socialite/ ?

I've written about these changes. Let me know if something is unclear, so I'll fix it before I announce it ;)

@aligajani
Copy link

Barry , thanks. I was looking for using Socialite with Satellizer! By the
way, Lumen and Laravel setup should be similar right ?

On Sunday, July 19, 2015, Barry vd. Heuvel notifications@github.com wrote:

Can you check out
http://barryvdh.nl/laravel/lumen/angular/2015/07/19/oauth-in-javascript-apps-with-angular-lumen-using-satellizer-laravel-socialite/
?

I've written about these changes. Let me know if something is unclear, so
I'll fix it before I announce it ;)


Reply to this email directly or view it on GitHub
#462 (comment).

Ali Gajani
Founder at Mr. Geek
www.mrgeek.me
www.aligajani.com

@barryvdh
Copy link
Contributor Author

Yes

@asantibanez
Copy link

Hi! Just started implementing Satellizer + Socialite. I am getting a server error with Socialite.

ClientException in Middleware.php line 69:
Client error: 400

I am trying to implement Google authentication. Any suggestions to debug this error? Thanks in advance.

@barryvdh
Copy link
Contributor Author

Catch the exception and print the response body.
Something like (string) $e->getResponse()->getBody()

@asantibanez
Copy link

Thanks @barryvdh. Sorry about the trouble. I had my route set to "any" verb instead of only "post". This resolved the issue with Socialite on the server side.

Your article http://barryvdh.nl/laravel/lumen/angular/2015/07/19/oauth-in-javascript-apps-with-angular-lumen-using-satellizer-laravel-socialite/ is fantastic. Thanks for the help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants