后端基于JWT实现注册登录
思维导图
登录原理
session
session是传统方法。
把一个网站所有的页面大致分为两类:
公开页面(未公开可以)login 页面 —— 与数据库一致,给用户发一个 sessionID,用户存到 cookie 中,每次请求访问时,将 cookie 中的 session 发给服务器
授权页面(登录后部分用户可见)—— 提取 cookie 中的 sessionID,判断是否有效,如果有效,则提取对应的用户信息到上下文中(一个 url 对应一个 Controller)
缺点:多端,跨域,多服务器分布式端,sessionID不好用。
JWT验证
具体可以参考这篇文章
JWT解决了session的缺点。
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
客户端使用用户名跟密码请求登录
服务端收到请求,去验证用户名与密码
验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
客户端每次向服务端请求 ...
配置Mysql与Spring Security模块
思维导图
应用模型:
SpringBoot 的角色是用来处理用户请求,client 端向 spring Boot 发送请求,然后向数据库请求数据,数据库返回数据给前端。
配置Mysql
下载并安装Mysql
配置环境变量
连接IDEA
mysql服务默认开机自动启动,如果向手动操作,可以参考如下命令:
关闭:net stop mysql80
启动:net start mysql80
Mysql常用命令
连接用户名为root,密码为xxxxxx的数据库服务:mysql -u root -p xxxxxx
列出所有数据库:show databases;
创建数据库:create database kob;
删除数据库:drop database kob;
使用数据库“kob”:use kob;
列出当前数据库的所有表:show tables;
创建名称为 user 的表,表中包含 id 和 username 两个属性:create table user(id int, username varchar(100));
删除表:drop table user;
在表中插入数据 ...
前端实现蛇
整体框架
实现蛇的头部
如何画蛇?
本质上蛇可以看做一堆各自组成的序列。
新建Cell.js,用于表示一个蛇的方块。
123456789export class Cell { constructor(r, c) { this.r = r; this.c = c; // 转换为 canvas 的坐标 this.x = c + 0.5; this.y = r + 0.5; }}
新建Snake.js对象
cells数组就用于存放蛇的“身体”。
123456789101112131415161718192021222324252627282930313233343536373839import { AcGameObject } from "./AcGameObject";import { Cell } from "./Cell";export class Snake extend ...
前端实现导航栏和游戏地图
思维导图
实现导航栏
老生常谈了,没啥好说的。随便去Bootstrap找个类改改构成基础部分
之后依据<router-link>和v-bind就能够实现基本的跳转。
组件NavBar.vue
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556<template> <nav class="navbar navbar-expand-lg navbar-light bg-light"> <div class="container"> <routerLink :class="route_name == 'home' ? 'nav-link active' : 'nav-link'" :to="{nam ...
项目概述和环境配置
项目设计
项目包含的模块
PK 模块:匹配界面(微服务)、实况直播界面(WebSocket 协议)
对局列表模块:对局列表界面、对局录像界面
排行榜模块:Bot 排行榜界面
用户中心模块:注册界面、登录界面、我的 Bot 界面、每个 Bot 的详情界面
前后端分离模式
SpringBoot 实现后端
Vue3 实现 Web 端和 AcApp 端
前端使用Vscode,后端使用IDEA。
解决前端跨域问题
在后端文件的根目录src/main/java/com/example/backend下,新建config文件夹,在该文件夹内,新建CorsConfig文件并写入以下代码:
123456789101112131415161718192021222324252627282930313233343536373839404142434445package com.example.backend.config;import org.springframework.context.annotation.Configuration;import javax.servlet.*;i ...
异常处理
异常是程序在执行期间产生的问题。C++ 异常是指在程序运行时发生的特殊情况,比如尝试除以零的操作。
异常提供了一种转移程序控制权的方式。C++ 异常处理涉及到三个关键字:try、catch、throw。
throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
catch: 在您想要处理问题的地方,通过异常处理程序捕获异常。catch 关键字用于捕获异常。
try: try 块中的代码标识将被激活的特定异常。它后面通常跟着一个或多个 catch 块。
如果有一个块抛出一个异常,捕获异常的方法会使用 try 和 catch 关键字。try 块中放置可能抛出异常的代码,try 块中的代码被称为保护代码。使用 try/catch 语句的语法如下所示:
123456789101112try { // 保护代码}catch( ExceptionName e1 ) { //catch 块}catch( ExceptionName e2 ) { //catch 块}catch( Ex ...
C++模板
非常感激我队友大爹给的复习资料
模板是泛型编程的基础,泛型编程即以一种独立于任何特定类型的方式编写代码。
模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。
每个容器都有一个单一的定义,比如 向量,我们可以定义许多不同类型的向量,比如 vector 或 vector 。
您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。
函数模板
模板函数定义的一般形式如下所示:
template
ret-type func-name(parameter list) { // 函数的主体 }
在这里,type 是函数所使用的数据类型的占位符名称。这个名称可以在函数定义中使用。
下面是函数模板的实例,返回两个数中的最大值:
实例
1234567891011121314151617181920212223242526272829#include <iostream>#include <string> using namespace std; template <typename T>inl ...
多态-类型兼容(基类和派生类)
非常感激我队友大爹提供的复习资料
定义
类型兼容规则是指在需要基类对象的任何地方, 都可以使用公有派生类的对象来替代。
类型兼容规则中所指的替代包括以下的情况:
派生类的对象可以隐含转换为基类对象;
派生类的对象可以初始化基类的引用;
派生类的指针可以隐含转换为基类的指针;
在替代之后, 派生类对象就可以作为基类的对象使用, 但只能使用从基类继承的成员。
可以说, 类型兼容原则是多态性的重要基础之一。
示例1
1234class B{};class D : public B {};B b, *pb;D d;
此时:
派生类对象可以隐含转换为基类对象, 即用派生类对象中从基类继承来的成员逐个赋值给基类对象的成员; b=d;
派生类的对象也可以初始化基类对象的引用; B& rb = d;
派生类对象的地址也可以隐含转换为指向基类的指针; pb = &d;
示例2
1234567891011121314151617181920212223242526272829303132333435363738394041#inclu ...
多态-纯虚函数和抽象类
定义
在C++中, 可以将虚函数声明为纯虚函数, 格式为:
1virtual 返回值类型 函数名 (函数参数列表) = 0;
纯虚函数没有函数体, 只有函数声明, 在虚函数声明的结尾加上=0, 表明此函数为纯虚函数。最后的=0并不表示函数返回值为0, 它只起形式上的作用, 告诉编译系统"这是纯虚函数"。
包含纯虚函数的类成为抽象类(Abstract Class)。之所以说它抽象, 是因为它无法被实例化, 也就是无法创建对象。原因很明显, 纯虚函数没有函数体, 不是完整的函数, 无法调用, 也无法为其分配内存空间。
抽象类通常是作为基类, 让派生类去实现纯虚函数, 派生类必须实现纯虚函数才能被实例化;
抽象基类处理约束派生类的功能, 还可以实现多态;
一个纯虚函数就可以使类成为抽象基类, 但是抽象基类除了包含纯虚函数之外, 还可以包含其他的成员函数(虚函数或普通函数)和成员变量;
只有类中的虚函数才能被声明为纯虚函数, 普通成员函数和顶层函数均不能被声明为纯虚函数;
示例
继承关系:Line --> Rectangle --> Cuboid -- ...
多态-虚函数
非常感激我队友大爹给我的复习资料
虚函数的作用
允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。
当把基类的某个成员函数声明为虚函数后,允许在其派生类中对该函数重新定义,赋予它新的功能,并且可以通过指向基类的指针指向同一类族中不同类的对象,从而调用其中的同名函数。由虚函数实现的动态多态性就是:同一类族中不同类的对象,对同一函数调用作出不同的响应。
有时在基类中定义的非虚函数会在派生类中被重新定义, 如果用基类指针调用该成员函数, 则系统会调用对象中基类部分的成员函数; 如果用派生类指针调用该成员函数, 则系统会调用派生类对象中的成员函数, 这并不是多态性行为(使用的是不同类型的指针), 没有用到虚函数的功能。
虚函数的使用方法
在基类用virtual声明成员函数为虚函数;这样就可以在派生类中重新定义此函数, 为它赋予新的功能, 并能被方便的调用。在类外定义虚函数时, 不必再加virtual;
在派生类中重新定义此函数, 要求函数名、函数类型、函数参数个数和类型全部与基类的虚函数相同, 并根据派生类的需要重新定义函数体;
定 ...