从零开始搭建聊天系统之客户端登录

必备:
1.lumen5.x version > 5.5+
2.redis
3.mysql

现在我们指定:
1.用户是用手机号做账户来登录
2.用户数据都使用缓存
3.用户登录也查询缓存,缓存查询不到再去数据库查询,并更新缓存
4.Redis用hash表维护用户数据
5.用户登录后,系统颁发一个Token凭据作为用户身份识别
6.token可以放到cookie
7.更新用户在线状态

那么流程应该是这样:


WechatIMG375.jpeg

router

$router->post('login', 'User\UserController@login');

create Model

where([
                'name'=>$data['name'],
                'password'=>$data['password']
            ])->first();
            if ($user){
                Redis::hset('user_name',$user->id,json_encode($user));
                $user = $user->toArray();
            }else{
                return [];
            }
        }

        return $user;
    }
}

create Controller

class UserController extends Controller
{
    const time = 3600000;
    

    public function login(Request $request):array
    {
        $data = $request->all();
        if (strlen($data['name']) == 11  && strlen($data['password']) >=6) {
            $data['password'] = md5($data['password']);
            $user = User::login($data);
            if ($user){
                $token = md5($data['name'] . $request->getClientIp().time());
                Redis::setex('token:'.$token,self::time,$user['id']);
                return ['code'=>200,'user'=>$user,'token'=>$token];
            }else{
                return ['code'=>400];
            }
        }

    }

创建表:


WechatIMG377.jpeg

插入模拟数据 name 为17612148988 password 为md5(227227)

现在我们通过POSTMAN测试下:


WechatIMG378.jpeg

检查Redis


WechatIMG379.jpeg

现在业务逻辑部分正常,现在我们来写html部分



现在我们来试试:


WechatIMG380.jpeg

WechatIMG381.jpeg

通过console.log打印我们可以在控制台和cookie看到成功打印出我们想要的数据,cookie也写入了token

创建Middleware中间件校验用户的登录状态

修改app.php引导文件注册路由中间件

$app->routeMiddleware([
   'login' => App\Http\Middleware\Login::class,
 ]);

新增route与校验登录令牌group

$router->group(['middleware' => 'login'],function ($router) {

    $router->get('index',['as' => 'index', function () {
        return view('Index.index');
    }]);

创建Index目录与index.balde.php文件

    
    
    
    

修改WebsocketController

public static function onMessage($client_id, $data)
    {
        if(!is_array($data)){
            $data = json_decode($data,true);
        }
        switch ($data['type']){
            case 0:
                $status = UserController::checkSocketToken($data);  //检查token合法性
                if($status){
                    //绑定uid,更改上线状态,通知该用户所有的好友
                    Gateway::bindUid($client_id, $data['uid']); 
                    Redis::set('bind:'.$client_id,$data['uid']);
                    GroupController::joinGroup($client_id);
                }
                break;
               //省略......
public static function checkSocketToken(array $data):bool {
        $tokenCache =  Redis::get('token:'.$data['token']);
        if($data['uid'] == $tokenCache){
            return true;
        }else{
            return false;
        }
    }

现在访问我们的登录页面登录成功后应该调整到ws链接页面,我们打开谷歌浏览器的控制台可以发现成功连接;


WechatIMG384.jpeg

WechatIMG383.jpeg

我们来分析ws代码

      //实例一个socket连接
       ws =  new WebSocket('ws://'+location.hostname+':8082');
      //在连接建立完成后发送数据给socket,其中携带了cookie的数据,实际是让服务器校验身份合法
        ws.onopen = function (e) {
            ws.send(JSON.stringify({type:0,token:$.cookie('token'),uid:$.cookie('uid')}));
        }
    //为了保活这个链接,我们需要心跳机制, js一个定时器,每10秒执行一次,与socket服务通讯
    var sh;
    sh = setInterval("sendHeartbeat()", 10000);

  function sendHeartbeat() {
    if(ws.readyState == 1){
        ws.send(JSON.stringify({type:'4'}));
    }
    if(ws.readyState == 3){
        layer.alert('与服务器链接中断,请检查网络');
        clearInterval(sh);

    }


你可能感兴趣的:(从零开始搭建聊天系统之客户端登录)