站长资源网络编程

基于Laravel Auth自定义接口API用户认证的实现方法

整理:jimmy2026/8/3浏览2
简介基于 laravel 默认的 auth 实现 api 认证现在微服务越来越流行了. 很多东西都拆分成独立的系统,各个系统之间没有直接的关系. 这样我们如果做用户认证肯定是统一的做一个独立的 用户认证 系统,而不是每个业务系统都要重新去写一遍用户认证相关的东西. 但是又遇到一个问题了. laravel

基于 laravel 默认的 auth 实现 api 认证

现在微服务越来越流行了. 很多东西都拆分成独立的系统,各个系统之间没有直接的关系. 这样我们如果做用户认证肯定是统一的做一个独立的 用户认证 系统,而不是每个业务系统都要重新去写一遍用户认证相关的东西. 但是又遇到一个问题了. laravel 默认的auth 认证 是基于数据库做的,如果要微服务架构可怎么做呢"color: #ff0000">实现代码如下:

UserProvider 接口:

// 通过唯一标示符获取认证模型
public function retrieveById($identifier);
// 通过唯一标示符和 remember token 获取模型
public function retrieveByToken($identifier, $token);
// 通过给定的认证模型更新 remember token
public function updateRememberToken(Authenticatable $user, $token);
// 通过给定的凭证获取用户,比如 email 或用户名等等
public function retrieveByCredentials(array $credentials);
// 认证给定的用户和给定的凭证是否符合
public function validateCredentials(Authenticatable $user, array $credentials);

Laravel 中默认有两个 user provider : DatabaseUserProvider & EloquentUserProvider.

DatabaseUserProvider

Illuminate\Auth\DatabaseUserProvider

直接通过数据库表来获取认证模型.

EloquentUserProvider

Illuminate\Auth\EloquentUserProvider

通过 eloquent 模型来获取认证模型

根据上面的知识,可以知道要自定义一个认证很简单。

自定义 Provider

创建一个自定义的认证模型,实现 Authenticatable 接口;

App\Auth\UserProvider.php

<"remember me" token.
 * @param mixed $identifier
 * @param string $token
 * @return \Illuminate\Contracts\Auth\Authenticatable|null
 */
 public function retrieveByToken($identifier, $token)
 {
 return null;
 }

 /**
 * Update the "remember me" token for the given user in storage.
 * @param \Illuminate\Contracts\Auth\Authenticatable $user
 * @param string   $token
 * @return bool
 */
 public function updateRememberToken(Authenticatable $user, $token)
 {
 return true;
 }

 /**
 * Retrieve a user by the given credentials.
 * @param array $credentials
 * @return \Illuminate\Contracts\Auth\Authenticatable|null
 */
 public function retrieveByCredentials(array $credentials)
 {
 if ( !isset($credentials['api_token'])) {
 return null;
 }

 return app(User::class)::getUserByToken($credentials['api_token']);
 }

 /**
 * Rules a user against the given credentials.
 * @param \Illuminate\Contracts\Auth\Authenticatable $user
 * @param array   $credentials
 * @return bool
 */
 public function validateCredentials(Authenticatable $user, array $credentials)
 {
 if ( !isset($credentials['api_token'])) {
 return false;
 }

 return true;
 }
}

Authenticatable 接口:

Illuminate\Contracts\Auth\Authenticatable
Authenticatable 定义了一个可以被用来认证的模型或类需要实现的接口,也就是说,如果需要用一个自定义的类来做认证,需要实现这个接口定义的方法。

<"htmlcode">
<"color: #ff0000">Guard 接口

Illuminate\Contracts\Auth\Guard

Guard 接口定义了某个实现了 Authenticatable (可认证的) 模型或类的认证方法以及一些常用的接口。

// 判断当前用户是否登录
public function check();
// 判断当前用户是否是游客(未登录)
public function guest();
// 获取当前认证的用户
public function user();
// 获取当前认证用户的 id,严格来说不一定是 id,应该是上个模型中定义的唯一的字段名
public function id();
// 根据提供的消息认证用户
public function validate(array $credentials = []);
// 设置当前用户
public function setUser(Authenticatable $user);

StatefulGuard 接口

Illuminate\Contracts\Auth\StatefulGuard

StatefulGuard 接口继承自 Guard 接口,除了 Guard 里面定义的一些基本接口外,还增加了更进一步、有状态的 Guard.
新添加的接口有这些:

// 尝试根据提供的凭证验证用户是否合法
public function attempt(array $credentials = [], $remember = false);
// 一次性登录,不记录session or cookie
public function once(array $credentials = []);
// 登录用户,通常在验证成功后记录 session 和 cookie 
public function login(Authenticatable $user, $remember = false);
// 使用用户 id 登录
public function loginUsingId($id, $remember = false);
// 使用用户 ID 登录,但是不记录 session 和 cookie
public function onceUsingId($id);
// 通过 cookie 中的 remember token 自动登录
public function viaRemember();
// 登出
public function logout();

Laravel 中默认提供了 3 中 guard :RequestGuard,TokenGuard,SessionGuard.

RequestGuard

Illuminate\Auth\RequestGuard

RequestGuard 是一个非常简单的 guard. RequestGuard 是通过传入一个闭包来认证的。可以通过调用 Auth::viaRequest 添加一个自定义的 RequestGuard.

SessionGuard

Illuminate\Auth\SessionGuard

SessionGuard 是 Laravel web 认证默认的 guard.

TokenGuard

Illuminate\Auth\TokenGuard

TokenGuard 适用于无状态 api 认证,通过 token 认证.

实现自定义 Guard

App\Auth\UserGuard.php

<"column" in persistent storage.
 *
 * @var string
 */
 protected $storageKey;

 /**
 * The user we last attempted to retrieve
 * @var
 */
 protected $lastAttempted;

 /**
 * UserGuard constructor.
 * @param UserProvider $provider
 * @param Request $request
 * @return void
 */
 public function __construct(UserProvider $provider, Request $request = null)
 {
 $this->request = $request;
 $this->provider = $provider;
 $this->inputKey = 'Authorization';
 $this->storageKey = 'api_token';
 }

 /**
 * Get the currently authenticated user.
 * @return \Illuminate\Contracts\Auth\Authenticatable|null
 */
 public function user()
 {
 if(!is_null($this->user)) {
  return $this->user;
 }

 $user = null;

 $token = $this->getTokenForRequest();

 if(!empty($token)) {
  $user = $this->provider->retrieveByCredentials(
  [$this->storageKey => $token]
  );
 }

 return $this->user = $user;
 }

 /**
 * Rules a user's credentials.
 * @param array $credentials
 * @return bool
 */
 public function validate(array $credentials = [])
 {
 if (empty($credentials[$this->inputKey])) {
  return false;
 }

 $credentials = [$this->storageKey => $credentials[$this->inputKey]];

 $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);

 return $this->hasValidCredentials($user, $credentials);
 }

 /**
 * Determine if the user matches the credentials.
 * @param mixed $user
 * @param array $credentials
 * @return bool
 */
 protected function hasValidCredentials($user, $credentials)
 {
 return !is_null($user) && $this->provider->validateCredentials($user, $credentials);
 }


 /**
 * Get the token for the current request.
 * @return string
 */
 public function getTokenForRequest()
 {
 $token = $this->request->header($this->inputKey);

 return $token;
 }

 /**
 * Set the current request instance.
 *
 * @param \Illuminate\Http\Request $request
 * @return $this
 */
 public function setRequest(Request $request)
 {
 $this->request = $request;

 return $this;
 }
}

在 AppServiceProvider 的 boot 方法添加如下代码:

App\Providers\AuthServiceProvider.php

<"auth:api".');
});
.
.
.

在 config\auth.php的 guards 数组中添加自定义 guard,一个自定义 guard 包括两部分: driver 和 provider.

设置 config\auth.php 的 defaults.guard 为 api.

<"guard" and password
 | reset options for your application. You may change these defaults
 | as required, but they're a perfect start for most applications.
 |
 */

 'defaults' => [
 'guard' => 'api',
 'passwords' => 'users',
 ],

 /*
 |--------------------------------------------------------------------------
 | Authentication Guards
 |--------------------------------------------------------------------------
 |
 | Next, you may define every authentication guard for your application.
 | Of course, a great default configuration has been defined for you
 | here which uses session storage and the Eloquent user provider.
 |
 | All authentication drivers have a user provider. This defines how the
 | users are actually retrieved out of your database or other storage
 | mechanisms used by this application to persist your user's data.
 |
 | Supported: "session", "token"
 |
 */

 'guards' => [
 'web' => [
  'driver' => 'session',
  'provider' => 'users',
 ],

 'api' => [
  'driver' => 'token',
  'provider' => 'token',
 ],
 ],

 /*
 |--------------------------------------------------------------------------
 | User Providers
 |--------------------------------------------------------------------------
 |
 | All authentication drivers have a user provider. This defines how the
 | users are actually retrieved out of your database or other storage
 | mechanisms used by this application to persist your user's data.
 |
 | If you have multiple user tables or models you may configure multiple
 | sources which represent each model / table. These sources may then
 | be assigned to any extra authentication guards you have defined.
 |
 | Supported: "database", "eloquent"
 |
 */

 'providers' => [
 'users' => [
  'driver' => 'eloquent',
  'model' => App\Models\User::class,
 ],

 'token' => [
  'driver' => 'token',
  'model' => App\Models\User::class,
 ],
 ],

 /*
 |--------------------------------------------------------------------------
 | Resetting Passwords
 |--------------------------------------------------------------------------
 |
 | You may specify multiple password reset configurations if you have more
 | than one user table or model in the application and you want to have
 | separate password reset settings based on the specific user types.
 |
 | The expire time is the number of minutes that the reset token should be
 | considered valid. This security feature keeps tokens short-lived so
 | they have less time to be guessed. You may change this as needed.
 |
 */

 'passwords' => [
 'users' => [
  'provider' => 'users',
  'table' => 'password_resets',
  'expire' => 60,
 ],
 ],

];

使用 方式:

基于Laravel Auth自定义接口API用户认证的实现方法

参考文章:地址

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。