【项目】星辰博客介绍

目录

一、项目背景

二、项目功能

1. 登录功能:

2. 列表页面:

3. 详情页面:

4. 写博客:

三、技术实现

四、功能页面展示

1. 用户登录

2. 博客列表页

3. 博客编辑更新页

4.博客发表页

5. 博客详情页

五.系统亮点

1.强制要求登陆

2.令牌技术


网站: 博客登陆页

账号: zhangsan 密码: 123456 或者 账号: lisi 密码: 123456

(欢迎大家登录测试,如果无法响应,请联系我重新部署,谢谢!)

一、项目背景


1. 星辰博客系统采用前后端分离的方法来实现,同时使用了数据库来存储相关的数据,同时将其部署到云服务器上。前端主要有四个页面构成:登录页、列表页、详情页以及编辑页,以上模拟实现了最简单的个人博客系统。其结合后端实现了以下的主要功能:登录、编辑博客、注销、删除博客、以及强制登录等功能。


2. 但是该项目没有设计用户注册功能,只能提前在数据库中存储用户信息后经过校验登录;并且用户头像不能自己设定,在进行前端页面的书写过程中已经将头像的图片写为静态了;而用户信息中的文章数以及分类数也没有在后端中具体实现,直接在前端页面中写为了静态的。


3. 该博客系统可以实现个人用户简单的博客记录,时间、标题、内容以及发布者等都可以进行详细地查看。


二、项目功能


该博客系统主要实现了以下几个功能:登录、注销、写博客以及删除博客等功能。

1. 登录功能:

用户名以及密码已经在后端写入了数据库,没有实现账户注册功能,即:用户名以及密码是已经存在的。登录成功后就会跳转到列表页面。在右上角存在主页和写博客两个按钮,但是在未登录情况下按下均只会跳转到登录页面。


2. 列表页面:

可以在列表页查看有限数量的博客简介,其包括博客标题、发布时间以及内容概要。在左侧可以看到登录的用户以及文章数、分类数等的模块。在右上角有主页、写博客和注销三个功能:主页即列表页,写博客即博客编辑页,注销即注销用户,回到登录页面。


3. 详情页面:

在列表页面点击“查看全文”按钮就会跳转到详情页,此时就可以看到该篇博客的完整内容。在右上角同样有主页、写博客、删除和注销四个功能:删除即删除该篇博客,删除之后就会跳转到列表页面,该篇博客就被成功删除。


4. 写博客:

在登录之后的任意界面点击“写博客”之后就会进入博客编辑页面,此时就可以进行博客的编写,点击“发布文章”后就可以成功发布文章,此时就会跳转到列表页。

三、技术实现

星辰博客系统采用Spring Boot作为核心框架,同时集成了SpringMVC、MyBatis等相关技术组件,构建了一个功能完备、性能优异的博客系统。具体技术实现如下:

  1. 基于Spring Boot框架构建Web应用程序,实现快速开发和部署。
  2. 采用MyBatis作为数据访问层框架,实现对数据库的CRUD操作。
  3. 使用Thymeleaf作为视图模板引擎,生成动态的HTML页面。
  4. 利用Markdown解析器实现博客文章的富文本编辑和展示。
  5. 采用Maven进行项目管理和构建,实现依赖管理和自动化构建部署。

四、功能页面展示

1. 用户登录

2. 博客列表页

3. 博客编辑更新页

4.博客发表页

5. 博客详情页

五.系统亮点

1.强制要求登陆

当⽤⼾访问博客列表⻚和博客详情⻚时,如果⽤⼾当前尚未登陆,就⾃动跳转到登陆⻚⾯. 采⽤拦截器来完成,token通常由前端放在header中,我们从header中获取token,并校验 token是否合法

添加拦截器

@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1. 从header中获取token//2. 校验token//3. 成功, 放行String userToken = request.getHeader(Constant.USER_TOKEN_HEADER);log.info("获得token, token:"+userToken);boolean result = JwtUtils.checkToken(userToken);if (result){return true;}else {response.setStatus(401);return false;}}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/**/*.html","/pic/**","/js/**","/css/**","/blog-editormd/**","/user/login"); //这里要排除登录页面}
}

1. 前端请求时,header中统⼀添加token,写在common.js中

$(document).ajaxSend(function (e, xhr, opt) { var user_token = localStorage.getItem("user_token"); xhr.setRequestHeader("user_token", user_token); });

效果展示

强制要求登陆展示

2.令牌技术

在我们实现登陆的时候

 传统思路:

• 登陆⻚⾯把⽤⼾名密码提交给服务器.

• 服务器端验证⽤⼾名密码是否正确,并返回校验结果给后端

• 如果密码正确,则在服务器端创建Session.通过Cookie把sessionId返回给浏览器.

有可能出现问题: 集群环境下无法直接使用Session.

如下场景:

1. 用户登录

用户登录请求,经过负载均衡,把请求转给了第⼀台服务器,第⼀台服务器进⾏账号密码 验证,验证成功后,把Session存在了第⼀台服务器上

2. 查询操作

用户登录成功之后,携带Cookie(里面有SessionId)继续执⾏查询操作,比如查询博客列表.此时请求转发到了第⼆台机器,第⼆台机器会先进⾏权限验证操作(通过SessionId验证⽤⼾是否 登录),此时第⼆台机器上没有该⽤⼾的Session,就会出现问题,提示用户登录,这是我们不能忍受的

问题出现的原因:

我们开发的项⽬,在企业中很少会部署在⼀台机器上,容易发⽣单点故障.(单点故障:⼀旦这台服务器挂 了,整个应⽤都没法访问了).所以通常情况下,⼀个Web应⽤会部署在多个服务器上,通过Nginx等进⾏ 负载均衡.此时,来⾃⼀个⽤⼾的请求就会被分发到不同的服务器上.

令牌技术可以解决如上场景:

1. 用户登录 用户登录请求,经过负载均衡,把请求转给了第⼀台服务器,第⼀台服务器进⾏账号密码 验证,验证成功后,⽣成⼀个令牌,并返回给客⼾端.

2. 客⼾端收到令牌之后,把令牌存储起来.可以存储在Cookie中,也可以存储在其他的存储空间.

3. 查询操作 用户登录成功之后,携带令牌继续执⾏查询操作,⽐如查询博客列表.此时请求转发到了 第⼆台机器,第⼆台机器会先进⾏权限验证操作.服务器验证令牌是否有效,如果有效,就说明用户已 经执行了登录操作,如果令牌是⽆效的,就说明用户之前未执⾏登录操作.

下面是JWT令牌⽣成和校验的部分源码:

1. 引⼊JWT令牌的依赖

<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.5</version><scope>runtime</scope></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is
preferred --><version>0.11.5</version><scope>runtime</scope></dependency>
public static String genToken(Map<String, Object> claim){return Jwts.builder().setClaims(claim).setExpiration(new Date(System.currentTimeMillis()+EXPIRATION_DATE)).signWith(key).compact();
}//生成keypublic static Claims parseToken(String token) {JwtParser build = Jwts.parserBuilder().setSigningKey(key).build();Claims body = null;try {body = build.parseClaimsJws(token).getBody();}catch (ExpiredJwtException e){log.error("token过期,校验失败,token:",token);} catch (Exception e) {log.error("token校验失败,token:",token);}return body;
}
public static boolean checkToken(String token) {Claims body = parseToken(token);if (body == null){return false;}return true;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/48611.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高性能图数据库Neo4j从入门到实战

图数据库Neo4j介绍 什么是图数据库&#xff08;graph database&#xff09; 随着社交、电商、金融、零售、物联网等行业的快速发展&#xff0c;现实社会织起了了一张庞大而复杂的关系网&#xff0c;传统数据库很难处理关系运算。大数据行业需要处理的数据之间的关系随数据量呈…

【数据结构】栈和队列的深度探索,从实现到应用详解

&#x1f48e;所属专栏&#xff1a;数据结构与算法学习 &#x1f48e; 欢迎大家互三&#xff1a;2的n次方_ &#x1f341;1. 栈的介绍 栈是一种后进先出的数据结构&#xff0c;栈中的元素只能从栈顶进行插入和删除操作&#xff0c;类似于叠盘子&#xff0c;最后放上去的盘子最…

广州机房搬迁网络部署方案

新机房网络部署应包括核心模块、业务模块、光传输模块、安全模块、流量采集模块、路由模块、带外管理模块等&#xff0c;每个模块都根据业务需求规划成多个POD&#xff08;Point Of Delivery&#xff0c;基本物理设计单元&#xff09;。 核心模块部署主要实现各业务模块的高速互…

HighConcurrencyCommFramework c++通讯服务器框架 :目录,修改标题,配置,日志打印

目录规划 nginx 根目录下的三个文件 makefile :编译项目的入口&#xff0c;编译项目从这里开始 config.mk&#xff1a;也是个配置脚本用来增加变动的东西&#xff0c;应付可变 common.mk&#xff1a;最核心的编译脚本&#xff0c;每个子目录都要被编译.cpp程序 配置文件 配…

postman创建mock server

B站博主的说明&#xff1a;

《python语言程序设计》第6章2题(求一个整数各个数字的和)编写一个函数

求一个整数各个数字的和编写一个函数&#xff0c;计算一个整数各个数字的和&#xff0c; def sumDigits(n):a n // 100b n % 100 // 10c n % 100 % 10print(f"{n}数&#xff0c;分成个&#xff0c;十&#xff0c;百&#xff0c;{a}{b}{c}", a b c)sumDigits(23…

算法日记day 16(二叉树的广度优先遍历|反转、对称二叉树)

一、二叉树的层序遍历 题目&#xff1a; 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3]…

SQUID - 形状条件下的基于分子片段的3D分子生成等变模型 评测

SQUID 是一个形状条件下基于片段的3D分子生成模型&#xff0c;给一个3D参考分子&#xff0c;SQUID 可以根据参考分子的形状&#xff0c;基于片段库&#xff0c;生成与参考分子形状非常相似的分子。 SQUID 模型来自于 ICLR 2023 文章&#xff08;2022年10月6日提交&#xff09;&…

vue+watermark-dom实现页面水印效果

前言 页面水印大家应该都不陌生&#xff0c;它可以用于验证数字媒体的来源和完整性&#xff0c;还可以用于版权保护和信息识别&#xff0c;这些信息可以在不影响媒体质量的情况下嵌入&#xff0c;‌并在需要时进行提取。‌本文将通过 vue 结合 watermark-dom 库&#xff0c;教大…

OpenCV 像素操作—证件照换底色详细原理 C++纯手写实现

文章目录 总体步骤1.RGB转HSV2.找出要换的底色3.取反&#xff0c;黑白颠倒4.将原图像的非背景部分复制到新背景上 完整代码1.C纯手写版2.官方API版本 总体步骤 1.RGB转HSV 为什么一定要转为HSV 颜色空间&#xff1f; 将图像从BGR颜色空间转换为HSV颜色空间是因为HSV颜色空间更…

nginx基本原理

进程模型 当nginx启动之后&#xff0c;会有一个master进程和多个worker进程。默认是一个worker进程。 master进程的作用&#xff1a;接收来自外界信号&#xff0c;向各worker进程发送信号&#xff0c;监控worker进程的运行状态&#xff0c;当worker进程在异常情况下退出后&am…

C#实现数据采集系统-实现功能介绍

系统介绍 我们这里主要使用C#( .Net 6)来实现一个数据采集系统&#xff0c;从0到1搭建数据采集系统&#xff0c;从系统分析&#xff0c;功能拆解&#xff0c;到一一实现 数据采集 数据采集是企业信息化和数字化转型过程中的关键环节&#xff0c;它涉及到从生产设备、传感器…

jupyter_contrib_nbextensions安装失败问题

目录 1.文件路径长度问题 2.jupyter不出现Nbextensions选项 1.文件路径长度问题 问题&#xff1a; could not create build\bdist.win-amd64\wheel\.\jupyter_contrib_nbextensions\nbextensions\contrib_nbextensions_help_item\contrib_nbextensions_help_item.yaml: No su…

【艺术向】【素描创作记录】《如何为你的红颜知己创作一幅画像(之二)》

写在前面 之前分析过类似的创作过程&#xff0c;见博客【艺术向】【素描创作记录】《如何为你的红颜知己创作一幅画像》 本人业余时间修习素描多年&#xff0c;在此撰文记录《如何为你的红颜知己创作一幅画像&#xff08;之二&#xff09;》&#xff0c;博得对方好感&#xff…

C++常见问题

一、C入门基础 1.1、函数重载 函数重载允许在同一作用域内定义多个同名函数&#xff0c;只要这个函数的参数列表&#xff08;即参数的数量&#xff0c;类型或者顺序不同&#xff09; 如何支持&#xff1a;程序经过编译后&#xff0c;编译器会对程序中的函数按一定规则进行重…

设计模式-Git-其他

目录 设计模式&#xff1f; 创建型模式 单例模式&#xff1f; 啥情况需要单例模式 实现单例模式的关键点&#xff1f; 常见的单例模式实现&#xff1f; 01、饿汉式如何实现单例&#xff1f; 02、懒汉式如何实现单例&#xff1f; 03、双重检查锁定如何实现单例&#xff…

封装MAVSDK为JAR包并导出给其它Android工程用完整示例

效果: 未解锁状态 已执行解锁指令 已执行起飞指令 飞行中 已执行降落指令 已执行返航指令 实现步骤: 1.准备PX4容器并启动:

ip地址是电脑还是网线决定的

在数字化时代的浪潮中&#xff0c;网络已经成为了我们日常生活和工作不可或缺的一部分。当我们谈论网络时&#xff0c;IP地址无疑是一个核心的概念。然而&#xff0c;关于IP地址的分配和决定因素&#xff0c;很多人可能存在误解。有些人认为IP地址是由电脑决定的&#xff0c;而…

springboot nacos的各种注解、手动操作监听配置变化(监听指定DataId/监听任何变化)

文章目录 springboot nacos监听配置变化&#xff08;监听指定DataId/监听任何变化&#xff09;监听任何配置变化Nacos注解NacosConfigurationPropertiesNacosValueNacosConfigListenerNacosInjectedNacosConfigServiceNacosNamingService springboot nacos监听配置变化&#xf…

QT--事件(丰富操作,高级功能)

一、事件 1.事件与信号的区别 事件来自外部&#xff0c;是随机发生的。信号来自内部&#xff0c;是主动发生的。有点像外中断和内中断的区别。事件&#xff1a;适用于处理系统级别的输入和状态变化&#xff0c;种类繁多&#xff0c;能够应对复杂的交互需求。信号/槽&#xff…