【问题标题】:Laravel 5.2 Authentication TokenLaravel 5.2 身份验证令牌
【发布时间】:2018-11-22 00:58:35
【问题描述】:

我正在尝试在 Laravel 5.2 中实现基于令牌的身份验证。我所做的是:

Routes.php

Route::group([
    'middleware' => ['auth:api']
], function() {
    Route::get('/api/reservation', 'apiController@get');
});

我已经修改了 User 模型并添加了api_token 字段并通过seeders添加了一个带有随机字符串的新用户:

迁移

Schema::table('users', function (Blueprint $table) {
            $table->string('api_token', 60)->unique()->nullable()->default(null);
        });

播种机

User::create([
            ...,
            'api_token' =>  str_random(60),
        ]);

控制器

class apiController extends Controller
{
    function get(Request $request) {
        return Reserva::all();
    }
}

然后,在Postman 中,我尝试使用我在数据库中的令牌获取添加/api/reservation?api_token=xxxxx 的url,但我总是得到未授权。奇怪的是,如果我在身份验证中间件上执行dd($this->auth),我会得到一个带有name='web'TokenGuard 对象。不应该是api吗?

可能是我理解错了,各位大神可以指点一下吗?谢谢

【问题讨论】:

  • 你想使用 Laravel Passport 吗?
  • 如果我可以让它在没有外部库的情况下工作,那将是完美的。否则我会使用它。

标签: php laravel rest authentication laravel-5.2


【解决方案1】:

您使用的 auth:api 中间件使用 Laravel Passport。如果您想要像创建自己的令牌一样基于自定义令牌的身份验证,则不能使用它。

如果您想使用 Passport,请执行以下操作:

保持这样的路线。需要认证的路由必须在auth:api中间件内。

您可以删除users 表的api_token 字段。迁移中的$table->rememberToken()函数和你想象的API token完全不同。事实上,令牌根本不存储在数据库中。您在数据库的 oauth_access_token 表中看到的令牌不是您用于 HTTP 请求的令牌。

不要像你一样创建自定义令牌。检查用户的登录名/密码对是否有效,生成一个令牌并将其返回给 API 的使用者,如下所示:

if (Auth::attempt(['login' => $req->login, 'password' => $req->password])) {
    $user = Auth::user();
    $token = $user->createToken('ToutelaBreizh')->accessToken;
    return response()->json(['token' => $token],200);
}

注意将登录/注册路由放置在auth:api 中间件之外,否则您需要为应该给您这个令牌的路由提供一个令牌 - 这是没有意义的。

接下来,请确保将令牌发送到请求的 Authorization 标头中的 API,而不是像您那样在请求参数中。在 Postman 中添加以下标题:

Authorization: Bearer your_token_retrieved_before

现在您几乎完成了,您可以将 API 与 Postman 一起使用。

【讨论】:

  • 我是将令牌存储在浏览器中的某处还是必须继续发送回令牌?
  • 您好,感谢您的回答。我不想要 API 中的 registration/login 逻辑,我只想要授权。这个想法是我希望应用程序外部的人能够对 url 执行 POST 并将一些数据保存在数据库中。我的想法是我必须将该令牌提供给客户,他将能够执行 POST 请求
  • @Vilius 你不应该在你的浏览器上使用 API,API 更适用于移动应用程序,但是假设你想创建一个从 API 获取内容的网站,你会必须调用登录路由,检索令牌,将其存储在浏览器的存储中,例如localStorage,并且每次调用 API 时都会在标头中发送令牌。 API 是无状态的,它不应该存储令牌,这样您就不必每次都重新发送它。
  • @JacopoStanchi ,对不起,这就是我的意思,感谢您的建议。前几天我在与VueJs 混在一起时苦苦挣扎
  • 这不是从 API 获取内容来呈现网站。它是关于通过 API 调用在两个 Web 应用程序中存储数据。他们在他们的网站中存储了一些数据,我们也必须拥有它,因此他们向我们的应用程序发出发布请求,数据被消耗并保存在我们的应用程序中。也许我没有解释自己。
【解决方案2】:

以防其他人遇到此问题。我的问题是在 Authenticate 中间件中。不知何故,我有一个旧版本。

我有这个Authenticate 中间件:

class Authenticate
{
    /**
     * The Guard implementation.
     *
     * @var Guard
     */
    protected $auth;

    /**
     * Create a new filter instance.
     *
     * @param  Guard  $auth
     * @return void
     */
    public function __construct(Guard $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($this->auth->guest()) {
            if ($request->ajax() || $request->wantsJson()) {
                return response('Unauthorized.', 401);
            } else {
                return redirect()->guest('login');
            }
        }

        return $next($request);
    }
}

我通过改变它来解决它:

class Authenticate
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->guest()) {
            if ($request->ajax() || $request->wantsJson()) {
                return response('Unauthorized.', 401);
            } else {
                return rediresct()->guest('login');
            }
        }

        return $next($request);
    }
}

【讨论】:

    猜你喜欢
    • 2016-09-21
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 1970-01-01
    • 2019-05-21
    • 2021-08-12
    • 2016-08-05
    相关资源
    最近更新 更多