User Registration for API / SPA

I am creating an API and a separate external application that will consume the specified API. In my specific case, I use Laravel Passport for my API and some VueJS for my external application.

In order for the user to create an account, the user must POST specify the route ( /oauth/token ) in the API to which client_secret must be client_secret ( https://laravel.com/docs/5.3/passport#password-grant-tokens ).

The only options I see are the following:

  • Having client_secret sent as a header from my external application. However, putting this token openly doesn't seem smart.
  • No client_secret is required client_secret all. This is not like option 1.
  • Have a dynamic page in my external application that can safely store client_secret and then send it to the API. Although this is obviously the most secure, it seems to partially downplay the goal of a fully static interface (SPA).

What is the best practice for this approach? I was looking for how this happens in general with the API and SPA, but I did not find anything that would point me in the right direction.

+7
csrf laravel jwt laravel-passport
source share
3 answers

From my point of view, the Laravel Passport component seems to be implementing the OAuth2 Framework protocol incorrectly.

The client_id and client_secret are not part of the grant type. For the grant type of the resource owner’s credentials, the required parameters are: username and password (see RFC6749 section 4.3.2 ).

client_id and client_secret are used to authenticate a confidential client that sends its credentials through body parameters (see RFC6749 section 2.3.1 ). The Laravel Passport component must allow other client authentication schemes (in particular, the basic HTTP authentication scheme). RFC6749 also indicates that

Including client credentials in the request body using two parameters is NOT RECOMMENDED and SHOULD be limited to clients who cannot directly use the basic HTTP authentication scheme

The OpenID Connect Core specification lists some of these schemes in section 9 . RFC6749 does not indicate how public clients (such as SPAs) should authenticate against the token endpoint. They should use an implicit permission type that does not require client authentication.

In any case, the solution may be to use a kind of proxy. This proxy server must be installed on the server. It will receive all requests from the SPA (without client secrecy), add the client secret and send the modified request to the Passar Laravel endpoint. Then the response is sent to the spa. Thus, the SPA never reveals the secret of the client.

+5
source share

I ran into the same issue and I did not find any more documentation on this issue.

So, here is what I did that seems wonderful, you will tell me if you see something wrong.

In my applications, I will use clients to provide the password that I create on the fly for each client of my application. By client, I mean a browser, or a mobile application, or something else.

Each browser checks at startup if they have client_id and client_secret in localStorage (or cookies or something else). Then, if they do not, they will name the endpoint of your API, which will create a client for providing the password and return the information to the browser.

Then the browser will be able to log in using this new client information and their credentials.

Here is the controller that I use to create the password submission client:

 <?php namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use Illuminate\Contracts\Hashing\Hasher; use Illuminate\Http\Request; use Laravel\Passport\ClientRepository; class AuthController extends Controller { protected $hasher; protected $clients; public function __construct (Hasher $hasher, ClientRepository $clients) { $this->hasher = $hasher; $this->clients = $clients; } public function makeClient (Request $request) { $client = $this->clients->create(null,$request->header('User-Agent','Unknown Device'), '', false, true); return $client->makeVisible('secret'); } } 

As you can see, as the name is for the client, I am trying to save the browser user-agent. Therefore, I can potentially display a page for my user with all his clients and give him the right to withdraw some clients, for example:

"Google Chrome, New York." You can also save the client IP address or anything there that will help you more accurately determine the type of client type ...

+4
source share

An easier way would be to take care of user registration with the Laravel application using Passport itself (and not with the Vuejs app interface via the API).
After registering the user and logging in, you can use the Passport CreateFreshApiToken to add a marker to the user's cookie when loading an external application. More problems with client_secret.

See https://laravel.com/docs/5.3/passport#consuming-your-api-with-javascript and https://mattstauffer.co/blog/introducing-laravel-passport#super-powered-access-to- the-api-for-frontend-views

Also oauth/token does not create the user I consider? It is assumed that he must provide a token (for the client to provide the password) or an authorization code (client for granting permissions).

-one
source share

All Articles