基于spring拦截器实现博客项目的强制登录功能(四)

6. 强制登录

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

6.1 添加拦截器

package com.example.spring_blog_24_9_8.config;
import com.example.spring_blog_24_9_8.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponseresponse, Object handler) throws Exception {//从header中获取tokenString jwtToken = request.getHeader("user_token");log.info("从header中获取token:{}",jwtToken);//验证⽤⼾tokenClaims claims = JwtUtils.parseToken(jwtToken);if (claims!=null){log.info("令牌验证通过, 放⾏");return true;}response.setStatus(401);return true;}
}
package com.example.spring_blog_24_9_8.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Arrays;
import java.util.List;
@Configuration
public class AppConfig implements WebMvcConfigurer {private final List excludes = Arrays.asList("/**/*.html","/blog-editormd/**","/css/**","/js/**","/pic/**","/login");@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns(excludes);}
}

6.2 实现客⼾端代码

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

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

        ajaxSend() ⽅法在 AJAX 请求开始时执⾏函数:

         event - 包含 event 对象

         xhr - 包含 XMLHttpRequest 对象

        options - 包含 AJAX 请求中使⽤的选项

        同时我们要注意引入common.js; 

 <script src="js/jquery.min.js"></script><script src="js/common.js"></script><script>getBlogList();function getBlogList(){$.ajax({type: "get",url: "/blog/getList",success:function (result){if(result.data != 0 && result.data.length>0 && result.code == 200 ){var finalHtml = "";for(var blog of result.data){finalHtml += '<div class="blog">';finalHtml += '<div class="title">' + blog.title + '</div>';finalHtml += '<div class="date">' + blog.createTime + '</div>';finalHtml += '<div class="desc">' + blog.content + '</div>';finalHtml += '<a class="detail" href="blog_detail.html?blogId=' + blog.id + '">查看全文&gt;&gt;</a>';finalHtml += '</div>';}$(".right").html(finalHtml);}},error:function (err){console.log(err);if(err!=null && err.status==401){alert("⽤⼾未登录, 即将跳转到登录⻚!");//已经被拦截器拦截了, 未登录location.href ="blog_login.html";}}})}</script>

         2. 修改 blog_datail.html

        访问⻚⾯时, 添加失败处理代码

        使⽤ location.href 进⾏⻚⾯跳转;

error:function (err){console.log(err);if(err!=null && err.status==401){alert("⽤⼾未登录, 即将跳转到登录⻚!");//已经被拦截器拦截了, 未登录location.href ="blog_login.html";}}

        修改 blog_list.html的部分代码如上故事;

 运行程序:浏览器访问博客列表页面:

        结果进入到登录页面;

7. 实现显⽰⽤⼾信息

        ⽬前⻚⾯的⽤⼾信息部分是写死的. 形如: 

        我们期望这个信息可以随着⽤⼾登陆⽽发⽣改变. :

        如果当前⻚⾯是博客列表⻚, 则显⽰当前登陆⽤⼾的信息.

         如果当前⻚⾯是博客详情⻚, 则显⽰该博客的作者⽤⼾信息.

        注意: 当前我们只是实现了显⽰⽤⼾名, 没有实现显⽰⽤⼾的头像以及⽂章数量等信息.

7.1 约定前后端交互接⼝

        在博客列表⻚, 获取当前登陆的⽤⼾的⽤⼾信息. 

[请求]
/user/getUserInfo
[响应]
{userId: 1,username: test...
}

        在博客详情⻚, 获取当前⽂章作者的⽤⼾信息

[请求]
/user/getAuthorInfo?blogId=1
[响应]
{userId: 1,username: test
}

7.2 实现服务器代码

        在 UserController添加代码 

 /*** 获取当前登录⽤⼾信息* @param request* @return*/@RequestMapping("/getUserInfo")public User getUserInfo(HttpServletRequest request){//从header中获取tokenString jwtToken = request.getHeader("user_token");//从token中获取⽤⼾idInteger userId = JwtUtils.getUserIdFromToken(jwtToken);//根据Userid获取⽤⼾信息if (userId!=null){return userService.selectById(userId);}return null;}/*** 获取博客作者信息* @param blogId* @return*/@RequestMapping("/getAuthorInfo")public Result getAuthorInfo(Integer blogId) {if (blogId == null && blogId < 1) {return Result.fail(-1, "博客ID不正确");}//根据博客id, 获取作者相关信息User user = userService.selectAuthorByBlogId(blogId);return Result.success(user);}

在UserService中添加代码

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;@Autowiredprivate  BlogMapper blogMapper;public User getUserInfo(String username){return userMapper.selectByName(username);}public User selectById(Integer Id){return  userMapper.selectById(Id);}public User selectAuthorByBlogId(Integer blogId) {//1. 根据博客ID, 获取作者ID//2. 根据作者ID, 获取作者信息Blog blog = blogMapper.selectById(blogId);if (blog==null && blog.getUserId()<1){return null;}User user = userMapper.selectById(blog.getUserId());return user;}
}

usermapper代码:

@Mapper
public interface UserMapper {@Select("select id, user_name, password, github_url, delete_flag, create_time " +"from user where id = #{id}")User selectById(Integer id);@Select("select id, user_name, password, github_url, delete_flag, create_time " +"from user where user_name = #{userName}")User selectByName(String name);}

7.3实现客⼾端代码

        修改 blog_list.html和 blog_detail.html代码

        在响应回调函数中, 根据响应中的⽤⼾名, 更新界⾯的显⽰.

function getUserInfo(url) {$.ajax({type: "get",url: url,success: function (result) {if (result.code == 200 && result.data != null) {$(".left .card h3").text(result.data.userName);$(".left .card a").attr("href", result.data.githubUrl);}}});
}

        由于该部分添加的代码一样,所以进行代码整合: 提取common.js,即将该部分代码放入到common.js中

function getUserInfo(url) {$.ajax({type: "get",url: url,success: function (result) {if (result.code == 200 && result.data != null) {$(".left .card h3").text(result.data.userName);$(".left .card a").attr("href", result.data.githubUrl);}}});
}

        分别在两个页面的<script>中引⼊common.js;

        blog_list.html 代码修改:

<script src="js/common.js"></script>
var userUrl= "/user/getUserInfo";
getUserInfo(userUrl);

        blog_detail.html 代码修改:

<script src="js/common.js"></script>
//获取作者信息
var userUrl= "/user/getAuthorInfo"+location.search;
getUserInfo(userUrl);

        效果展示:成功登录到博客列表页;

当前是用户沈梦瑶的博客列表页:

        当前是用户袁一琦的博客列表页: 

        用户沈梦瑶点击袁一琦写的博客的详情页,显示的是作者袁一琦的信息:

        在该页面点击github地址,我们的页面跳转到袁一琦的gitee的首页,也就是我的码云首页,如下所示:

ps:本文就写到这里了,谢谢观看 

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

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

相关文章

性能测试-jmeter的控制器(十六)

一、if控制器 需求&#xff1a;使用“用户自定义变量”定义name变量&#xff0c;值可以是“baidu”或“itcast”,使用变量值&#xff0c;控制是否访问对应网站。 1、步骤&#xff1a; 在测试计划中添加用户定义的变量name,取值可为baidu或itcast添加两个http请求&#xff1a…

misc音频隐写

一、MP3隐写 &#xff08;1&#xff09;题解&#xff1a;下载附件之后是一个mp3的音频文件&#xff1b;并且题目提示keysyclovergeek;所以直接使用MP3stego对音频文件进行解密&#xff1b;mp3stego工具是音频数据分析与隐写工具 &#xff08;2)mp3stego工具的使用&#xff1a;…

CSS实现前端布局更巧妙的方案!在 flex 布局中通过使用 margin 实现水平垂直居中以及其他常见的前端布局

在前端开发中&#xff0c;实现水平垂直居中一直是个热门话题。随着 CSS Flexbox 布局的普及&#xff0c;开发者们开始更多地使用 justify-content 和 align-items 这两个属性来解决这个问题。 然而&#xff0c;还有一种更加简洁、灵活的方式——使用 margin: auto; 来实现居中以…

大数据之Flink(二)

4、部署模式 flink部署模式&#xff1a; 会话模式&#xff08;Session Mode&#xff09;单作业模式&#xff08;Per-Job Mode&#xff09;应用模式&#xff08;Application Mode&#xff09; 区别在于集群的生命周期以及资源的分配方式&#xff1b;以及应用的main方法到底在…

Vue3使用vue-qrcode-reader实现扫码绑定设备功能

需求描述 移动端进入网站后&#xff0c;登录网站进入设备管理界面。点击添加设备&#xff0c;可以选择直接添加或者扫一扫。点击扫一扫进行扫描二维码获取设备序列号自动填充到添加设备界面的序列号输入框中。然后点击完成进行设备绑定。 安装vue-qrcode-reader 这里使用的版…

2024.9.11 作业

绘制组件制作时钟 代码&#xff1a; /*******************************************/ 文件名&#xff1a;widget.h /*******************************************/ #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPaintEvent> #include &l…

MAX3483ESA+T具有±15kV ESD保护的+3.3V、低功耗收发器,适用于RS-485和RS-422通信

MAX3483ESAT具有15kV ESD保护的3.3V、低功耗收发器&#xff0c;适用于RS-485和RS-422通信。每个器件包含一个驱动器和一个接收器。MAX3483ESAT具有限摆率驱动器&#xff0c;可充分降低EMI并减少因电缆端接不当引起的反射&#xff0c;从而实现数据速率高达250kbps的无误差数据传…

【中间件】-容器编排平台Kubernetes简介

目录 什么是K8s 为什么需要K8s 什么是容器(Contianer) K8s能做什么&#xff1f; K8s的架构原理 控制平面(Control plane) kube-apiserver etcd kube-scheduler kube-controller-manager cloud-controller-manager 小结 节点组件(Node) container runtime Pod kubelet ku…

AnyChart 数据可视化框架

AnyChart 数据可视化框架 AnyChart 是一个灵活的 JavaScript&#xff08;HTML5、SVG、VML&#xff09;图表框架&#xff0c;适合任何需要数据可视化的解决方案。 目录 下载并安装开始插件将 AnyChart 与 TypeScript 结合使用将 AnyChart 与 ECMAScript 6 结合使用技术集成贡献…

Anolis OS 7.9(龙蜥操作系统)上Oracle12C Release 2 (12.2)打补丁

本文的oracle使用的是单实例环境 一、打补丁前环境准备 1、确保make, ar, ld,和 nm四个可执行命令在$PATH中 export PATH$PATH:/bin2、查看已装的Oracle的OPatch版本 #切换到oracle用户 su - oracle#进入到数据库的安装目录下的opatch目录 cd /ora01/app/oracle/product/12…

JS_函数声明

JS中的方法,多称为函数,函数的声明语法和JAVA中有较大区别 函数说明 函数没有权限控制符不用声明函数的返回值类型,需要返回在函数体中直接return即可,也无需void关键字参数列表中,无需数据类型调用函数时,实参和形参的个数可以不一致声明函数时需要用function关键字函数没有…

github actions CICD简单使用案例

参考&#xff1a; https://developer.aliyun.com/article/1540773 https://github.com/ViggoZ/producthunt-daily-hot/blob/main/.github/workflows/generate_markdown.yml 1、创建github项目 目录&#xff1a; .github/workflows/fetch-news.yml actions执行yaml&#xff08;…

C语言 | Leetcode C语言题解之第397题整数替换

题目&#xff1a; 题解&#xff1a; //第一种动态规划:超时 // class Solution { // public: // int integerReplacement(int n) { // vector<int>dp(n1,0); // dp[1]0; // for(int i2;i<n;i){ // if(i%20){ // …

Vue接入高德地图并实现基本的路线规划功能

目录 一、申请密钥 二、安装依赖 三、代码实现 四、运行截图 五、官方文档 一、申请密钥 登录高德开放平台&#xff0c;点击我的应用&#xff0c;先添加新应用&#xff0c;然后再添加Key。 如图所示填写对应的信息&#xff0c;系统就会自动生成。 二、安装依赖 npm i am…

学生签到系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;学生管理&#xff0c;教师管理&#xff0c;签到信息管理&#xff0c;学生签到管理&#xff0c;班课信息管理&#xff0c;加入班课管理&#xff0c;课程信息管理 微信端账号功能包括&#xff1a;系统首…

C++(三)----内存管理

1.C/C内存分布 看下面这个问题&#xff08;考考你们之前学的咋样&#xff09;&#xff1a; int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";char* pCh…

JDK 安装及配置教程(Windows)【安装】

文章目录 一、 下载1. 官网下载2. 其它渠道 二、 安装三、 配置四、 验证五、 双 JDK 环境 软件 / 环境安装及配置目录 一、 下载 1. 官网下载 安装地址&#xff1a;https://www.oracle.com/ 打开浏览器输入网址 https://www.oracle.com/index.html&#xff0c;进入 Oracle …

Python——turtle库(海龟绘图)介绍与使用

一、概述 在 Python 中&#xff0c;海龟绘图提供了一个实体“海龟”形象&#xff08;带有画笔的小机器动物&#xff09;&#xff0c;假定它在地板上平铺的纸张上画线。 二、运行环境 本文运行环境&#xff1a;Windows11&#xff0c;Python3.11&#xff0c;Pycharm2023.1.4 使…

哈佛斯坦福大学团队联合发布病理基础模型CHIEF,全面提升癌症诊断的准确性|顶刊精析·24-09-12

小罗碎碎念 今日顶刊&#xff1a;Nature 今天精读的这篇文章于24-09-04发表于Nature&#xff0c;作者来自哈佛大学、斯坦福大学。 作者角色作者姓名单位名称&#xff08;英文&#xff09;单位名称&#xff08;中文&#xff09;第一作者Xiyue WangDepartment of Biomedical Info…

如何快速清理Docker中的停止容器?

如何快速清理Docker中的停止容器? 方法一:使用`docker container prune`方法二:结合`docker ps`和`docker rm`注意(这些命令慎用,确定容器不需要之后再执行)💖The Begin💖点点关注,收藏不迷路💖 Docker容器在停止后可能会占用不必要的磁盘空间。如何清理这些停止的…