本文章主要讲解仿百度云盘功能存储的一个开发笔记:
- 基于Nginx作为反向代理和轻量级web服务器
- 客户端使用Qt搭建,后台应用使用Go-Gin框架开发。
- 分布式解决方案用Go-Fastdfs,简介和安装部署可参考Go-Fastdfs安装部署。
- 数据存储使用mysql和redis进行缓存。
注册和登录功能模块设计
注册:
注册过程中的用户重要信息(如密码)不应该明文保存到数据库,所有我们通过MD5加密后再保存到数据库中。
登录:
登录流程中是使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端生成一个 Token,这个Token可以存储在内存、磁盘、或者数据库里,再把这个 Token 发送给客户端
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
客户端的实现
登录和注册窗口我们使用QT中的StackedWidget容器来实现:
commom类主要实现配置文件读取和一些通用的工具
#ifndef COMMON_H
#define COMMON_H
#include <QDebug>
#define cout qDebug() << "[ " << __FILE__ << ":" << __LINE__ << " ] " //没有分号
#include <QWidget>
#include <QString>
#include <QListWidgetItem>
//文件信息
struct FileInfo
{
QString md5; //文件md5码
QString filename; //文件名字
QString user; //用户
QString time; //上传时间
QString url; //url
QString type; //文件类型
qint64 size; //文件大小
int shareStatus; //是否共享, 1共享, 0不共享
int pv; //下载量
QListWidgetItem *item; //list widget 的item
};
//窗口在屏幕中央显示
void moveToCenter(QWidget *tmp);
//从配置文件中得到相对应的参数
QString getCfgValue(QString title, QString key, QString path="../conf/cfg.json");
//通过读取文件, 得到文件类型, 存放在typeList
void getFileTypeList();
//得到文件后缀,参数为文件类型,函数内部判断是否有此类型,如果有,使用此类型,没有,使用other.png
QString getFileType(QString type);
//登录信息,登陆信息需要加密后,才写入配置文件
void writeLoginInfo(QString user, QString pwd, bool isRemeber, QString path="../conf/cfg.json");
//服务器信息,写入配置文件
void writeWebInfo(QString ip, QString port, QString path="../conf/cfg.json");
//获取某个文件的md5码
QString getFileMd5(QString filePath);
//将某个字符串加密成md5码
QString getStrMd5(QString str = "");
//产生分隔线
QString getBoundary();
//得到服务器回复的状态码, 返回值为 "000", 或 "001"
QString getCode(QByteArray json);
//传输数据记录到本地文件,user:操作用户,name:操作的文件, code: 操作码, path: 文件保存的路径
void writeRecord(QString user, QString name, QString code, QString path="../conf/record/");
#endif // COMMON_H
loginwidget实现登录窗体
#ifndef LOGINWIDGET_H
#define LOGINWIDGET_H
#include <QWidget>
#include <QPaintEvent>
#include <QPoint>
#include <QMouseEvent>
#include <QNetworkAccessManager>
#include "mainwidget.h"
namespace Ui {
class LoginWidget;
}
class LoginWidget : public QWidget
{
Q_OBJECT
public:
explicit LoginWidget(QWidget *parent = 0);
~LoginWidget();
protected:
void paintEvent(QPaintEvent *); //绘图事件,画背景图
void mousePressEvent(QMouseEvent *e); //鼠标点击,获取点击坐标,处理移动
void mouseMoveEvent(QMouseEvent *e); //鼠标移动,移动窗口
private slots:
void on_closeButton_clicked();
private:
Ui::LoginWidget *ui;
QPoint p; //处理窗口移动需要使用到的坐标
//读取配置信息,设置默认登录状态,默认设置信息
void readCfg();
QNetworkAccessManager *manager;
MainWidget *mainWidget;//主界面,显示用户文件列表
};
#endif // LOGINWIDGET_H