John Dorean John Dorean -3 years ago 74
PHP Question

Implementing OAuth 2.0 authentication with a Laravel API

I'm currently building a web application which is an AngularJS frontend that communicates with a RESTful API built using Laravel. I'm making good progress, but finding it hard to get my head around how to handle user authentication.

I've been advised that I should be using OAuth for authentication, and I've decided to use it seen as it could be a learning experience for me as well. The package I'm using to handle this is oauth2-server-laravel.

The basic user story is that users can register their username/password combination for the application, and they then log into the application with that same username and password. They're only authenticated by their username and password, and not by any client secret. After login, they should be given an access token which will be send along with every future request to authenticate them on different API endpoints.

The OAuth2 library has a "password flow" grant type which seems to be what I need, however it also takes

client_id
and
client_secret
parameters, which I don't want. The request URI is something like this:

POST https://www.example.com/oauth/access_token?
grant_type=password&
client_id=the_client_id&
client_secret=the_client_secret&
username=the_username&
password=the_password&
scope=scope1,scope2&
state=123456789


But what I want is just:

POST https://www.example.com/oauth/access_token?
grant_type=password&
username=the_username&
password=the_password


How am I meant to provide a client ID and secret of a user that has yet to authenticate?

Is there a different grant I can be using, or is what I want to achieve just not suited for OAuth at all?

Answer Source

Take into account, that client id and client secret aren't parameters that you have to force your end-user to pass. They are static and defined in/for your client app (angular app in this case).

All you need to do is to create a record for your main app in oauth_clients table, and create a scope with full access in oauth_scopes table, and send this values when requesting token.

And that's all in fact.

Also, you may want to consider using implicit grant flow in case of building js-only application, because storing client secret and refresh token in a js app is insecure. Using implicit grant in a final product may look like login window on soundcloud and is more secure as the token is obtained server-side without exposing client secret.

Another way to go, if you still want to use password flow is creating a proxy for refreshing tokens. Proxy can hide your refresh token in encrypted http-only cookie, and your js-app don't ask your api for new token, but the proxy instead. Proxy reads refresh token from encrypted cookie, asks the api for new token and returns it. So the refresh token is never exposed. If you set token ttl for an hour let's say, then stealing a token would be quite "pointless*" in case of a normal application, and stealing refresh token would be "impossible*".

*Of course if someone really want he probably could hack it any way.

And yeah, i know this all looks a bit hacky - modal windows for logging in, proxy etc. But also searching on this topic i couldn't find any better and more elegant way of doing it. I think that's still a lack that all js-apps have to deal with if you want a token based authentication.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download