I am creating an API and a separate front-end app that will consume said API. In my particular case I'm using Laravel Passport for my API and some VueJS for my frontend app.
In order for a user to create an account, a user must POST
to a route (/oauth/token
) on the API which, requires a client_secret
to be passed (https://laravel.com/docs/5.3/passport#password-grant-tokens).
The only options I see are:
- Having the
client_secret
sent as a header from my frontend app. However, putting this token out in the open doesn't seem smart. - Don't require the
client_secret
at all. This doesn't seem much better than option 1. - Have a dynamic page on my frontend app that can securely store the
client_secret
and then send it to the API. While this is obviously the most secure, it seems to partially defeat the purpose of a fully static frontend (SPA).
What's the best practice for this type of approach? I've searched for how this is dealt with in general with an API and SPA, but I haven't found anything that points me in the right direction.
I came across the same problem, and I didn't find much more documentation on the problem.
So here is what I did, that seems working great so far, you'll tell me if you see anything wrong.
For my apps, I'll be using password grant clients that I create on the fly for each "client" of my app. By client I mean browser, or mobile app, or anything.
Each browser, checks at startup if they have any client_id and client_secret into localStorage (or cookies, or anything). Then, if they don't, they call an endpoint of your API that will create a password grant client and return the information to the browser.
The browser will then be able to login the user using this new client information and his credentials.
Here is the controller I use to create a password grant client:
As you can see, as the name for the client, I try to store the User-Agent of the browser. So I can potentially display a page to my user with all his clients and giving him the right to revoke some clients like:
"Google Chrome, New York". You can also store the client IP or anything in there that will help you identify more precisely the client type of device...