API/SPA的用户注册

tpt*_*cat 7 csrf jwt laravel vue.js laravel-passport

我正在创建一个API和一个单独的前端应用程序,它将使用所述API.在我的特殊情况下,我使用Laravel Passport作为我的API,并使用一些VueJS作为我的前端应用程序.

为了让用户创建一个帐户,用户必须使用API​​上的POSTroute(/oauth/token),这需要client_secret传递(https://laravel.com/docs/5.3/passport#password-grant-tokens).

我看到的唯一选择是:

  1. 具有client_secret发送,从我的前端应用程序的标题.但是,将此令牌放在公开状态似乎并不聪明.
  2. 根本不需要client_secret.这似乎没有比选项1好多少.
  3. 在我的前端应用程序上有一个动态页面,可以安全地存储client_secret然后将其发送到API.虽然这显然是最安全的,但似乎部分地破坏了完全静态前端(SPA)的目的.

这种方法的最佳实践是什么?我已经搜索了如何通过API和SPA处理这个问题,但我没有找到任何指向正确方向的东西.

Flo*_*lli 5

从我的角度来看,Laravel Passport组件似乎错误地实现了OAuth2框架协议.

client_idclient_secret参数不许可类型的一部分.对于资源所有者密码凭据授予类型,所需参数为usernamepassword(请参阅RFC6749第4.3.2节).

client_idclient_secret用于验证通过正文参数发送其凭据的机密客户端(请参阅RFC6749第2.3.1节).Laravel Passport组件应该允许其他客户端身份验证方案(尤其是HTTP基本身份验证方案).RFC6749也表明了这一点

使用这两个参数在请求体中包含客户端凭据是不推荐的,并且应该仅限于无法直接使用HTTP Basic身份验证方案的客户端

OpenID Connect Core规范在其第9节中列出了其中一些方案.RFC6749未指示公共客户端(例如SPA)应如何针对令牌端点进行身份验证.它们应该使用不需要客户端身份验证的隐式授权类型.

无论如何,解决方案可能是使用一种代理.此代理必须安装在服务器上.它将接收来自SPA的所有请求(没有客户端密钥),添加客户端密钥并将修改后的请求发送到Laravel Passport端点.然后将响应发送到SPA.这样SPA就不会暴露客户的秘密.


Ham*_*bot 4

我遇到了同样的问题,并且没有找到有关该问题的更多文档。

这就是我所做的,到目前为止似乎效果很好,如果你发现任何问题,请告诉我。

对于我的应用程序,我将使用我为应用程序的每个“客户端”动态创建的密码授予客户端。我所说的客户端是指浏览器、移动应用程序或任何其他东西。

每个浏览器在启动时都会检查 localStorage 中是否有 client_id 和 client_secret (或 cookies 或其他任何东西)。然后,如果他们不这样做,他们会调用 API 的端点,该端点将创建密码授予客户端并将信息返回到浏览器。

然后,浏览器将能够使用此新的客户端信息及其凭据登录用户。

这是我用来创建密码授予客户端的控制器:

<?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');
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,作为客户端的名称,我尝试存储浏览器的用户代理。因此,我可以向我的用户显示一个包含其所有客户的页面,并赋予他撤销某些客户的权利,例如:

“谷歌浏览器,纽约”。您还可以存储客户端 IP 或任何有助于您更准确地识别客户端设备类型的内容...

  • 这个问题我太感兴趣了,我开始悬赏100 (2认同)