likes
comments
collection
share

laravel+react实战打造企业级高并发分布式电商小程序(一)-- 基础建设

作者站长头像
站长
· 阅读数 29

laravel+react实战打造企业级高并发分布式电商小程序(一)

整体使用laravel7+react打造整个电商小程序。里面会涉及到高并发的知识,mysql的分库分表,主从读写分离的配置,redis集群的使用,缓存系统的使用,队列系统的使用等。

先初始化一个laravel的项目。然后配置好.env文件。

基础建设

我们使用前后端分离就要考虑跨域问题和安全问题。跨域使用cors解决,laravel7里面内置了cors的解决方案,我们只要修改config/cors.php配置文件就好了。

把里面的值更改一下。修改这个值的原因是因为我们会使用jwt传一个token的请求头过来进行验证。这个时候还是报跨域的错误,所以将supports_credentials值修改为true,如果不报错就不需要修改了。


'supports_credentials' => true,

把这个参数的值修改为true。

安全问题使用jwt的解决方案,安装jwt的包。

composer require lcobucci/jwt

在routes/api.php路由文件中增加下面的路由


//获取jwt token
Route::post('/require_token', 'JWT\RequireTokenController@requireToken');

在config下面新建jwt.php文件,里面内容如下


<?php

return [
    'JWT_SECRET' => env('JWT_SECRET','DvYUz+woS7vVJe6ldY+PqWoUbhIyY9rShzM0NAfzxdU='),
    'JWT_EXP_TIME' => env('JWT_EXP_TIME','36000'),
];

.env中增加下面的内容


# jwt
JWT_SECRET=DvYUz+woS7vVJe6ldY+PqWoUbhIyY9rShzM0NAfzxdU=   
JWT_EXP_TIME=36000  //过期时间

app/http/middleware中创建中间件jwtCheck.php,内容如下


<?php

namespace App\Http\Middleware;

use App\Models\Sys\ErrorModel;
use Closure;
use \Lcobucci\JWT\Parser;
use \Lcobucci\JWT\Signer\Hmac\Sha256;

class jwtCheck
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {

        $parser = new Parser;
        $signer = new Sha256;
        $secret = config('jwt.JWT_SECRET');

        if($request->hasHeader('Authorization')){
            $token = $request->header('Authorization');
            //解析token
            $parse = $parser->parse($token);
            //验证token合法性
            if (!$parse->verify($signer, $secret)) {
                return response()->json(['code'=>ErrorModel::JWT_ERROR, 'msg'=>'令牌错误!']);
            }

            //验证是否已经过期
            if ($parse->isExpired()) {
                return response()->json(['code'=>ErrorModel::JWT_ERROR, 'msg'=>'令牌过期!']);
            }
        }else{
            return response()->json(['code'=>ErrorModel::JWT_ERROR, 'msg'=>'令牌缺失!']);
        }
        //把token放到参数里面
        request()->offsetSet('token', $token);
        return $next($request);
    }
}

app/http下面的Kernel.php文件里面的$routeMiddleware变量里面增加下面内容,把中间件注册到系统中。

'jwtCheck' => \App\Http\Middleware\jwtCheck::class,

控制器

创建控制器

app/http/controller下面创建jwt文件夹,然后在jwt文件夹里面创建RequireTokenController.php文件。


<?php

namespace App\Http\Controllers\JWT;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use \Lcobucci\JWT\Builder;
use \Lcobucci\JWT\Signer\Hmac\Sha256;
use Illuminate\Support\Facades\Redis;

class RequireTokenController extends Controller
{
    public function requireToken(Builder $builder, Sha256 $signer) {

        $secret = config('jwt.JWT_SECRET');
        $time = time();
        $expTime = config('jwt.JWT_EXP_TIME');

        do {
            //设置header和payload,以下的字段都可以自定义
            $builder->setIssuer("cmp.wliot.com") //发布者
                    ->setAudience("cmp.wliot.com") //接收者
                    ->setId("abc", true) //对当前token设置的标识
                    ->setIssuedAt($time) //token创建时间
                    ->setExpiration($time + $expTime) //过期时间
                    // ->setNotBefore($time + 5) //当前时间在这个时间前,token不能使用
                    ->set('uid', 30061); //自定义数据

            //设置签名
            $builder->sign($signer, $secret);
            //获取加密后的token,转为字符串
            $token = (string)$builder->getToken();
        } while (Redis::exists($token));
        //存入redis
        // Redis::setex($token, $expTime, json_encode([]));

        return $this->success($token);
    }
}

在这里面使用到了$this->success()方法,这个方法来自controller类,我们需要编写这个方法。

app/http下面创建Utils文件夹,在里面创建Success.php文件。


<?php

namespace App\Http\Utils;

use App\Models\Sys\ErrorModel;

trait Success {

    function success($data = []) {
        $res = ['code'=>'0','msg'=>'请求成功!', 'data'=>$data];
        return response()->json($res);
    }
}

修改app/http/controllers/controller.php文件


use App\Http\Utils\Success;  //引入刚才的文件

class Controller extends BaseController {
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests, Success;  //在这里添加Success 也就是刚才的文件。
}

在这里面使用到了redis,所以我们需要启动你本地的redis服务器。启动之后就可以访问我们上面填写的路由了,使用postman访问你的路由。

laravel+react实战打造企业级高并发分布式电商小程序(一)-- 基础建设

可以看到返回了正确的token。

在后面的访问请求中我们需要使用这个token。我们把它加入请求头。在请求头新建一个Authorization的key,他的值就是我们的token。