Laravel 5.2 身份验证令牌

Posted

技术标签:

【中文标题】Laravel 5.2 身份验证令牌【英文标题】:Laravel 5.2 Authentication Token 【发布时间】: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 吗? 如果我可以让它在没有外部库的情况下工作,那将是完美的。否则我会使用它。 【参考方案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);
    

【讨论】:

以上是关于Laravel 5.2 身份验证令牌的主要内容,如果未能解决你的问题,请参考以下文章

如何在 laravel 5.2 中使用多重身份验证 [关闭]

在 laravel 5.2 中使用默认身份验证路由对用户进行身份验证后设置会话数据

Laravel 5.2 - 方法身份验证不存在

Laravel 5.2 身份验证不起作用

laravel 5.2 身份验证 - 缺少链接

我正在尝试为 user 和 admin 实现 laravel 5.2 多重身份验证。但是未定义身份验证用户提供程序 [] 错误给出