2023-12-18 14:37:31
浏览数 (18)
前言
- 公司用go-zero弄了一个统一账号中心服务
- 部分项目的后台用
dcat-admin搭建后台, 也去调用账号中心的用户去登录, 记录一下过程
环境依赖
proto的二进制文件https://github.com/protocolbuffers/protobuf/releases- 这个直接参考官方文档安装好https://cloud.google.com/php/grpc?hl=zh-cn#windows
windows的直接去https://pecl.php.net/package/grpc去下载对应PHP版本的ddl文件就可以- 然后安装
grpc和protobuf composer require "grpc/grpc:^1.38"composer require "google/protobuf:^3.17"
- 因为服务器我用的是
docker,我使用https://github.com/mlocati/docker-php-extension-installer来辅助安装 install-php-extensions grpccomposer require "grpc/grpc:^1.38"composer require "google/protobuf:^3.17"
- 生成
grpc风格的PHP代码还需要grpc_php_plugin插件 - 官方安装方式https://github.com/grpc/grpc/blob/v1.58.0/src/php/README.md#grpc_php_plugin-protoc-plugin
windows偷懒版本https://github.com/lifenglsf/grpc_for_windows
- 然后根据自己的
proto文件生成PHP文件后复制到项目里
代码
代码语言:javascript
复制<?php
namespace AppAdminControllers;
use AppServicesAccountRpc;
use DcatAdminAdmin;
use DcatAdminHttpControllersAuthController as BaseAuthController;
use DcatAdminModelsAdministrator;
use IlluminateHttpRequest;
use IlluminateSupportFacadesHash;
use IlluminateSupportFacadesLog;
use IlluminateSupportFacadesValidator;
class AuthController extends BaseAuthController
{
public function postLogin(Request $request)
{
$username = $request->input('username');
$password = $request->input('password');
$remember = (bool)$request->input('remember', false);
$admin = Administrator::query()->firstOrNew([
'username' => $username
]);
// 用户已经存在, 去查找密码
if ($admin->exists) {
// 检查密码
if (!Hash::check($password, $admin->password)) {
return $this->validationErrorsResponse([
$this->username() => '密码错误',
]);
}
// 查看 token 是否还有效
try {
// 可以获取到信息, 那么直接登录
$res = AccountRpc::me($admin->remember_token);
$this->guard()->login($admin, $remember);
return $this->sendLoginResponse($request);
} catch (Exception $e) {
Log::error($e);
}
}
try {
$res = AccountRpc::login($username, $password);
} catch (Exception $e) {
return $this->validationErrorsResponse([
$this->username() => 'rpc:' . $e->getMessage(),
]);
}
// 如果这个用户没有, 那么就去创建管理员
$admin->name = $res->getUser()->getNickname();
$admin->password = Hash::make($password);
$admin->remember_token = $res->getSession()->getToken();
$admin->save();
$this->guard()->login($admin, $remember);
return $this->sendLoginResponse($request);
}
public function getLogout(Request $request)
{
$admin = $this->guard()->user();
try {
// rpc 调用
AccountRpc::logout($admin->remember_token);
} catch (Exception $e) {
Log::error($e->getMessage());
}
$this->guard()->logout();
$request->session()->invalidate();
$path = admin_url('auth/login');
if ($request->pjax()) {
return "<script>location.href = '$path';</script>";
}
return redirect($path);
}
}
代码语言:javascript
复制<?php
namespace AppServices;
use AccountAccountClient;
use ReflectionClass;
class AccountRpc
{
protected static $client;
public static function login($username, $password)
{
$meta = [
'appId' => ['test'],
'groupId' => ['test'],
];
// 注意设置超时时间
list($res, $status) = self::client()->Auth(new AuthRequest(), $meta, ['timeout' => 3 * 1000 * 1000])->wait();
if ($status->code !== 0) {
throw new Exception($status->details);
}
return $res;
}
public static function me($token){}
public static function logout($token){}
public static function client()
{
if (is_null(self::$client)) {
self::$client = new AccountClient(config('rpc.account'), [
'credentials' => GrpcChannelCredentials::createInsecure(),
]);
}
return self::$client;
}
}
问题
- 代码在本地运行起来是没问题, 但是部署到测试环境发现
rpc请求会阻塞, 然后查了一下才知道grpc扩展和swoole扩展有冲突https://github.com/hhxsv5/laravel-s/issues/281 - 由于我使用的是
laravel-s, 所以也有相同的问题, 解决方法在Dockerfile文件加以下配置
代码语言:javascript
复制### ... 在 install grpc 后面加
RUN install-php-extensions pcntl redis pdo_mysql zip bcmath gd grpc
RUN echo "grpc.enable_fork_support = 1" >> /usr/local/etc/php/conf.d/docker-php-ext-grpc.ini &&
echo "grpc.poll_strategy = epoll1" >> /usr/local/etc/php/conf.d/docker-php-ext-grpc.ini