如何构建私有服务器到客户端API? Laravel Passport?

时间:2018-02-11 19:39:39

标签: laravel axios laravel-passport

我不确定我是否使用正确的方法处理我的问题。

我想通过Axios获得信息。例如:调用:/ api /用户使用Axios会让我成为用户,但我不希望在访问domain.test / api / user时看到信息。

即使用户是访客,我甚至想要使用API​​调用来获取函数结果

我安装了Laravel Documentation for API上的所有内容,但我仍然不确定用户如何获取令牌。

所以,如果我打电话:

axios.get('/api/user')
    .then(response => {
        console.log(response.data);
    }); 

我从网络标签{" message":" Unauthenticated。"}。 (我没有忘记设置:... Middleware \ CreateFreshApiToken :: class以及所有内容)。

我认为我的问题是我没有正确注册用户。我拿了两把钥匙怎么办?

然后很奇怪,阅读博客https://laravelcode.com/post/laravel-passport-create-rest-api-with-authentication,他们使用

$success['token'] =  $user->createToken('MyApp')->accessToken;

但我不明白。我在哪里保存?我非常困惑,因为每个关于Laravel Passport的博客完全不同。

或者我做错了吗?

1 个答案:

答案 0 :(得分:4)

Passport是一个OAuth2服务器实现,它提供了几种不同的授权策略。虽然可以使用Passport进行身份验证,但其主要目的是授权。这是通过token scopes完成的。您选择发布的令牌类型取决于您对API的预期目的以及您的预期目标将消耗您的API。

让我们从以下开始:

$success['token'] =  $user->createToken('MyApp')->accessToken;

他们正在创建Personal Access Tokens。这是消费api最简单的方法,因为客户端可以根据需要自己创建令牌并且使用寿命很长。

Password Grant策略也是不错的选择。使用此策略时的常用方法是在内部代理对Passport的身份验证,并将客户端ID和机密合并到中间件中的请求中。

public function handle($request, $next) {
    return $next(tap($request, function($request) {
        $request->merge([
             'client_id' => config('services.passport.client.id'),
             'client_secret' => config('services.passport.client.secret')
        ]);
        // do any other pre-request work needed here 
    }));
}

<强>设置

要开始使用Passport,请运行命令:

php artisan passport:install

这将创建加密密钥以及个人访问和密码授予客户端类型,这些类型将存储在oauth_clients表中的数据库中。

警卫和中间件

API路由需要使用api保护,通过在路由组或Controller构造函数上设置auth:api中间件来完成。

// using via constructor 
public function __construct()
{
    $this->middleware('auth:api');
}

// via a route group
Route::group(['middleware' => ['auth:api'], function() {
    // your api routes 
});

护照路线

您的用户模型需要使用特征HasApiTokens以及AuthServiceProvider方法中的Passport::routes()来电boot

public function boot()
{
    $this->registerPolicies();

    Passport::routes();

    // this is also an ideal time to set some token expiration values
    Passport::tokensExpireIn(now()->addDays(15));
    Passport::refreshTokensExpireIn(now()->addDays(30));
}

要使用个人访问令牌策略进行身份验证,您需要创建自己的登录和注销路由,而不是使用内置的Laravel身份验证机制。

Referring to the tutorial in your question,他们定义了以下路线:

Route::post('login', 'API\PassportController@login');
Route::post('register', 'API\PassportController@register');

,登录方法实现为:

public function login(){
    if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){
        $user = Auth::user();
        $success['token'] =  $user->createToken('MyApp')->accessToken;
        return response()->json(['success' => $success], $this->successStatus);
    }
    else{
        return response()->json(['error'=>'Unauthorised'], 401);
    }
}

预计带有电子邮件和密码的ajax请求将发布到login,如果成功,则会使用访问令牌进行响应。

存储/使用令牌

此令牌必须存储在客户端,例如,存储在cookie或本地存储中,然后添加到客户端的每个请求中。您将在客户端请求中将令牌添加到Authorization标头。

// Use a response interceptor to check for a token and put it in storage 
axios.interceptors.response.use(response => {
  // store the token client side (cookie, localStorage, etc)
  if (response.data.token) {
    localStorage.setItem('token', token)
  }
  return response
}, error => {
  // Do something with response error
  return Promise.reject(error);
});

// Use a request interceptor to add the Authorization header
axios.interceptors.request.use(config => {
  // Get the token from storage (cookie, localStorage, etc.)
  token = localStorage.getItem('token')
  config.headers.common['Authorization'] = `Bearer ${token}`
  return config;
}, error => {
  // Do something with request error
  return Promise.reject(error);
});

访问经过身份验证的用户

为了吸引用户,请将'api'参数传递给auth()辅助工具,Auth外观或通过请求:

$user = auth('api')->user();

$user = Auth::user('api');

$user = request()->user('api');

请记住,个人访问令牌是长期存在的,因此由您决定何时以及如何过期。

任何http客户端都可用于发出api请求,axios是一个非常常见的选项,并包含在每个Laravel安装中。