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

How to construct a private sever-to-client-side API? Laravel Passport?

我不确定我是否使用了正确的方法来解决我的问题。

我想通过 Axios 获取 信息。例如:用axios调用:/api/user让我得到用户,但是我不想看到我继续domain.test[=43=的信息].

我什至想使用 API 调用来获取函数结果 即使用户是访客。

我为 API 安装了 Laravel 文档中的所有内容,但我仍然不确定用户如何获取令牌。

所以如果我调用:

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 的博客都完全不同。

还是我做错了?

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 table。

保护和中间件

API 路由需要使用 api 守卫,通过在路由组或控制器构造函数上设置 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 并在 boot 方法中的 AuthServiceProvider 调用 Passport::routes() 中。

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,如果成功,它会返回一个访问令牌。

Storing/Using 令牌

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

// 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 安装中。