微服务(二) php laravel 用户客户端

微服务(二) php laravel 用户客户端

本节主要讲解通过laravel 作为客户端调用go kratos 服务端,实现用户注册登录

环境

docker desk
laradock
laravel

环境准备

  1. 通过laradock php-fpm 安装 grpc protobuf
  2. workspace 安装protoc安装 protoc 与 grpc_php_plugin 可执行文件(这个plugin创建整很久)
  3. 为方便把grpc_php_plugin放到GRPC文件目录
  4. 在worksapce使用protoc 与 grpc_php_plugin 生成客户端代码
protoc --proto_path=./ --php_out=./php-src/ --grpc_out=./php-src/ --plugin=protoc-gen-grpc=./grpc_php_plugin  ./api/user/v1/user.proto

生成客户端代码

在这里插入图片描述

实现

  1. 添加客户端调用服务层代码
    在这里插入图片描述
  2. 添加grpc 调用组件及GRPC服务的自动加载
composer require grpc/grpc
composer require google/protobuf

grpc 服务文件自动加载

"autoload": {
        "psr-4": {
            "App\\": "app/",
            "Database\\Factories\\": "database/factories/",
            "Database\\Seeders\\": "database/seeders/",
            "GPBMetadata\\":"GRPC/php-src/GPBMetadata/",
            "":"GRPC/php-src/"
        }
    },
  1. 增加jwt 中间件
composer require firebase/php-jwt

添加中间件app/Http/Middleware/ApiJwt.php

<?php
namespace App\Http\Middleware;
use App\Service\Jwt;
use Closure;
use Illuminate\Http\Request;
class ApiJwt
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
     * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
     */
    public function handle(Request $request, Closure $next)
    {
        //将token放入header中传输
        $token = $request->header('Authorization');
        if (!$token) {
            return response()->json(['code' => 500, 'msg' => 'token不存在', 'data' => []]);
        }
        $result = Jwt::decodeToken($token);
        if ($result) {
            //将加密id解密传入下一步
            $request->attributes->add(['user_id' => $result->user_id, 'nickname' => $result->nickname]);
        } else {
            return response()->json(['code' => 500, 'msg' => 'token过期', 'data' => []]);
        }
        return $next($request);
    }
}

添加jwt 服务app/Service/Jwt.php

<?php
namespace App\Service;
use Firebase\JWT\JWT as JwtService;
use Firebase\JWT\Key;
class Jwt
{
    protected static $key = 'laravel-tiway';
    //加密
    public static function createToken($userId, $nickname)
    {
        $payload = array(
            "iss" => "http://example.org",
            "aud" => "http://example.com",
            'exp' => time() + (24 * 3600),
            'user_id' => $userId,
            'nickname' => $nickname,
        );
        $jwt = JwtService::encode($payload, self::$key, 'HS256');
        return $jwt;
    }
    //解密
    public static function decodeToken($jwt)
    {
        $decoded = JwtService::decode($jwt, new Key(self::$key, 'HS256'));
        if ($decoded) {
            return $decoded;
        } else {
            return false;
        }
    }
}
  1. 实现登录注册 app/Http/Controllers/UserController.php
<?php
namespace App\Http\Controllers;
use App\Service\GrpcUser;
use App\Service\Jwt;
use Illuminate\Http\Request;
class UserController extends Controller
{
    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function register(Request $request)
    {
        $input = $request->only('nickname', 'mobile', 'password');
        //用户手机号码是否已注册
        $user = GrpcUser::getUserByMobile($input['mobile']);
        if (isset($user['id'])) {
            throw new \Exception('手机号码已被注册');
        }
        //创建用户
        $user = GrpcUser::CreateUser($input['nickname'], $input['mobile'], $input['password']);
        if (!isset($user['id'])) {
            throw new \Exception('创建失败');
        }
        return response()->json([
            'success' => true,
            'data' => $user
        ], 200);
    }
    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function login(Request $request)
    {
        $input = $request->only('mobile', 'password');
        //是否已经存在相同手机号码
        $isLogin = GrpcUser::checkoutUserPassword($input['mobile'], $input['password']);
        if (!$isLogin) {
            throw new \Exception('账号或密码错误');
        }
        //获取用户信息
        $user = GrpcUser::getUserByMobile($input['mobile']);
        //jwt
        if (isset($user['id'])) {
            $token = Jwt::createToken($user['id'], $user['nickname']);
        }
        return response()->json([
            'success' => true,
            'token' => $token,
        ]);
    }
    /**
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function getUser(Request $request)
    {
        $userId = $request->attributes->get('user_id');
        $user = GrpcUser::getUserById($userId);
        return response()->json(['user' => $user]);
    }
}

代码参考:laravel-tiway

总结

  1. 后期有时间把用户信息全部添加一个redis 缓存
  2. 简化controller,添加仓库层实现数据
  3. 如果你也是用docker desk,为求方便,联系我,我将提供workspace 和php-fpm 的镜像压缩包
                       

点击阅读全文

上一篇 2023年 6月 14日 am10:27
下一篇 2023年 6月 14日 am10:28