您可以创建自己的身份验证保护,它也非常简单但更复杂。
- 创建一个将实现可验证接口的类。
- 创建用户提供者。
- 创建一个新的守卫。
- 在 AuthServiceProvider 中注册 Guard 和 UserProvider。
- 在 config/auth.php 中添加提供者和守卫
- 使用你的新后卫。
优点
- 您不必修改身份验证端点
- 您不必更改默认守卫
- 你基于 Laravel Auth 系统
- 保持对浏览器中多个选项卡的支持
- 可与网卫同时使用
- 保留使用 PresenceChannel 的所有优势
缺点
所以,
1. 创建一个将实现 Authenticable 接口的新类。
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use JsonSerializable;
/**
* @property string $id
* @property string $name
*/
class Session implements Authenticatable, Jsonable, Arrayable, JsonSerializable
{
private $id;
private $attributes = [];
public function __construct($id)
{
$this->id = $id;
$this->name = "Guest";
}
/**
* Get the name of the unique identifier for the user.
*
* @return string
*/
public function getAuthIdentifierName()
{
return 'id';
}
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier()
{
return $this->{$this->getAuthIdentifierName()};
}
/**
* Get the password for the user.
*
* @return string
*/
public function getAuthPassword()
{
return "";
}
/**
* Get the token value for the "remember me" session.
*
* @return string
*/
public function getRememberToken()
{
return $this->{$this->getAuthIdentifierName()};
}
/**
* Set the token value for the "remember me" session.
*
* @param string $value
* @return void
*/
public function setRememberToken($value)
{
$this->{$this->getRememberToken()} = $value;
}
/**
* Get the column name for the "remember me" token.
*
* @return string
*/
public function getRememberTokenName()
{
return "token";
}
public function __get($name)
{
return $this->attributes[$name];
}
public function __set($name, $value)
{
$this->attributes[$name] = $value;
}
/**
* Convert the object to its JSON representation.
*
* @param int $options
* @return string
*/
public function toJson($options = 0)
{
return json_encode($this);
}
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray()
{
return $this->attributes;
}
/**
* Specify data which should be serialized to JSON
* @link https://php.net/manual/en/jsonserializable.jsonserialize.php
* @return mixed data which can be serialized by <b>json_encode</b>,
* which is a value of any type other than a resource.
* @since 5.4.0
*/
public function jsonSerialize()
{
return $this->attributes;
}
}
根据需要修改它,但你不应该序列化 $id 属性
2.创建用户提供者
<?php namespace App\Extensions;
use App\Models\Session;
use Illuminate\Cache\Repository;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Support\Fluent;
use Illuminate\Support\Str;
class SessionUserProvider implements UserProvider
{
private $store;
/**
* SessionUserProvider constructor.
* @param Repository $store
*/
public function __construct(Repository $store)
{
$this->store = $store;
}
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
return new Session(
$this->getUniqueTokenForSession($identifier)
);
}
/**
* Retrieve a user by their unique identifier and "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 void
*/
public function updateRememberToken(Authenticatable $user, $token)
{
return;
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
return null;
}
private function unpack($data)
{
return json_decode($data);
}
private function getUniqueTokenForSession($id)
{
return $this->retrieveCacheDataForSession($id)
->get('uuid');
}
private function retrieveCacheDataForSession($id)
{
$fluent = new Fluent(
$this->unpack(
$this->store->has($id) ? $this->store->get($id) : "[]"
)
);
if(!$fluent->__isset('uuid')) {
$fluent->__set('uuid', Str::random(128));
}
$this->store->put($id, $fluent->toJson(), 60 * 60 * 60);
return $fluent;
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
return null;
}
}
如果您使用广播, retrieveById方法中的标识符属性始终是会话 ID,因此您也可以将其用作令牌。
3.创建新的Guard
<?php namespace App\Services\Auth;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Http\Request;
class GuestGuard implements Guard
{
private $user;
protected $request;
protected $provider;
/**
* GuestGuard constructor.
* @param UserProvider $provider
* @param Request $request
*/
public function __construct(UserProvider $provider, Request $request)
{
$this->provider = $provider;
$this->request = $request;
}
/**
* Determine if the current user is authenticated.
*
* @return bool
*/
public function check()
{
return !is_null($this->user);
}
/**
* Determine if the current user is a guest.
*
* @return bool
*/
public function guest()
{
return !$this->check();
}
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
if($this->check()) {
return $this->user;
}
$this->setUser(
$this->provider->retrieveById(
$this->request->session()->getId()
)
);
return $this->user;
}
/**
* Get the ID for the currently authenticated user.
*
* @return int|null
*/
public function id()
{
return !is_null($this->user) ? $this->user->id : null;
}
/**
* Validate a user's credentials.
*
* @param array $credentials
* @return bool
*/
public function validate(array $credentials = [])
{
return false;
}
/**
* Set the current user.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return void
*/
public function setUser(Authenticatable $user)
{
$this->user = $user;
}
}
在用户方法中,您将会话 ID 作为标识符传递,仅使用广播此方法是必要的。
4、在AuthServiceProvider中注册Guard和UserProvider。
// app/Providers/AuthServiceProvider.php
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::provider('sessions', function (Application $app) {
return new SessionUserProvider(
$app->make('cache.store')
);
});
Auth::extend('guest', function (Application $app, $name, array $config) {
return new GuestGuard(Auth::createUserProvider($config['provider']), $app->make('request'));
});
}
5.1 在 config/auth.php 中添加提供者
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// New
'sessions' => [
'driver' => 'sessions',
'model' => App\Models\Session::class,
],
],
5.2 在 config/auth.php 中添加保护
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
// New
'guest' => [
'driver' => 'guest',
'provider' => 'sessions'
]
],
6.使用你的新后卫
// routes/channels.php
Broadcast::channel('chat.{id}', function (Authenticatable $user){
return $user;
}, ['guards' => ['guest']]);
请注意,您可以同时使用 'web' 作为守卫('web' 应该在 'guest' 之前)。它允许您找出谁是访客以及谁是登录用户 - 您可以在通道回调中检查 Authenticable 的实例。
以及它在 laravel-echo-server 数据库中的外观