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

news2024/11/14 18:34:22

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 {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse
            response, Object handler) throws Exception {
        //从header中获取token
        String jwtToken = request.getHeader("user_token");
        log.info("从header中获取token:{}",jwtToken);
        //验证⽤⼾token
        Claims 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"
    );
    @Autowired
    private LoginInterceptor loginInterceptor;
    @Override
    public 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中获取token
        String jwtToken = request.getHeader("user_token");
        //从token中获取⽤⼾id
        Integer 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 {
 @Autowired
 private UserMapper userMapper;
 @Autowired
 private  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.coloradmin.cn/o/2127210.html

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

相关文章

k8s dashboard token 生成/获取

创建示例用户 在本指南中&#xff0c;我们将了解如何使用 Kubernetes 的服务帐户机制创建新用户、授予该用户管理员权限并使用与该用户绑定的承载令牌登录仪表板。 对于以下每个和的代码片段ServiceAccount&#xff0c;ClusterRoleBinding您都应该将它们复制到新的清单文件(如)…

Blazor开发框架Known-V2.0.10

Known今天迎来了2.0的第11个版本&#xff0c;同时网站网址和板块也进行了一次升级改造&#xff0c;虽不完美&#xff0c;但一直在努力改变&#xff0c;之前一直在完善框架功能&#xff0c;忽略了文档的重要性&#xff0c;所以这次更新了文档和API。交流互动板块也在进行当中&am…

PPT幻灯片的添加与编辑:全面技术指南

目录 一、PPT幻灯片的添加 1.1 启动PowerPoint与新建演示文稿 1.2 选择模板 1.3 添加新幻灯片 1.3.1 使用“开始”选项卡 1.3.2 使用快捷键 1.3.3 复制现有幻灯片 1.4 调整幻灯片顺序 二、PPT幻灯片的编辑 2.1 输入与编辑文本 2.1.1 使用文本框添加文本 2.1.2 使用占…

GitHub Star 数量前 13 的自托管项目清单

一个多月前&#xff0c;我们撰写并发布了这篇文章《终极自托管解决方案指南》。在那篇文章里我们深入探讨了云端服务与自托管方案的对比、自托管的潜在挑战、如何选择适合自托管解决方案&#xff0c;并深入介绍了五款涵盖不同场景的优秀自托管产品。 关于自托管的优势&#xf…

职业技能大赛背景下的移动互联网应用软件开发(Android)实训室建设方案

一、建设背景 随着科技的持续进步&#xff0c;移动设备已成为人们日常生活中不可或缺的一部分。据相关数据&#xff0c;移动互联网的使用率在近年来显著上升。在这样的背景下&#xff0c;移动互联技术不仅推动了科技的发展&#xff0c;也渗透到了智能家居、车联网、工业自动化…

大数据-129 - Flink CEP 详解 Complex Event Processing - 复杂事件处理

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

改进版field-sensitive指针分析算法

DEA 1.Introduction2.Approach2.1.Stride-based Field Representation2.1.1.示例12.1.2.示例2 2.2.完整算法 3.Evaluation3.1.Implementation3.2.结果 参考文献 1.Introduction 这篇paper是SVF团队对PKH field-sensitive指针分析算法 [ 2 ] ^{[2]} [2] 的优化&#xff0c;在使…

Pycharm中python文件导入torch模块时报错:No module named ‘torch‘

问题描述 导入torch时报错 上网查找后&#xff0c;发现原因可能是没有安装pytorch&#xff0c;但检查后发现自己已经安装了&#xff0c;遂考虑到可能是没有使用正确的环境 解决方法 因为是PyCharm 没有使用我所安装了 PyTorch 的 Conda 环境&#xff0c;所以报错了&#xf…

计算2的100次方

#include <stdio.h>int main() {int a[100] {0};a[0] 1;for(int i 0;i < 100;i)//乘100次2{for(int j 0; j < 100;j)//乘以每一位{a[j] * 2;//每一位都*2}for(int k 0;k < 99;k){if(a[k] > 10)//判断进位{a[k 1];a[k] - 10;}}}//找到第一个不为0的数&a…

vue part 9

动画与过渡 Test.vue <template><div><button click"isShow !isShow">显示/隐藏</button><transition name"hello" appear><h1 v-show"isShow">你好啊!</h1></transition><transition …

51单片机快速入门之点灯 STC 51单片机

第一步创建工程 第二步加载头文件 第三步编写代码 点灯完成 解释:主函数为main() 内部P1控制的是p1.0-p1.7 引脚 0为低电平

银河麒麟国产化系统(或者是Linux)一键安装docker和docker-compose

在国产化化机器上离线安装docker和docker-compose 第一步&#xff0c;查询国产化系统的cpu架构 使用如下命令都可以查询出来&#xff1a; # 查询全部 uname -a # 只查询部分 uname -p # 查了cpu 列表 lscpu 查询示例如下&#xff1a; 为麒麟桌面版 为麒麟服务版 第二步&a…

人工智能领域各方向顶级会议和期刊

会议 人工智能基础与综合&#xff1a;AAAI、CICAI (!)、UAI、IJCAI 机器学习&#xff1a;COLT、ICLR、ICML、NeurIPS 模式识别与计算机视觉&#xff1a;ECCV、CVPR、ICCV 语言与语音处理&#xff1a;ACL、EMNLP 知识工程与数据挖掘&#xff1a;SIGKDD、SIGMOD、ICDE、SIGIR、V…

golang-基础知识(array, slice, map)

1. array array就是数组&#xff0c;我们可以通过如下方式定义一个数组并对数组中的元素进行赋值 var arr [n]type // 定义一个大小为n&#xff0c;类型为type的数组 arr[0] xx // 对数组中的元素进行赋值 其中[n]type中&#xff0c;n表示数组的长度&#xff0c;type表示数…

【数字】xilinx的AXI VIP如何使用的guide

AXI 验证 IP (VIP)AXI Stream VIP 可用于为支持定制 RTL 设计流程的 AXI 主设备及 AXI 从设备验证连接和基本功能性。此外&#xff0c;它还支持贯通模式&#xff0c;该模式明显有助于用户监控事务处理信息&#xff0f;吞吐量或驱动有源激励。AXI VIP 提供的实例测试台和测试可演…

SolidWorks 质量属性和截面属性

系列文章目录 前言 SOLIDWORKS 应用程序根据模型几何体和材料属性计算质量、密度、体积等属性。 您可覆盖某些属性的计算值。 您可查看以下质量属性&#xff1a; 零件多实体零件中的实体装配体装配体中的零部件 在零件或装配体中&#xff0c;您可查看面和草图的区域属性。 您可…

【HarmonyOS NEXT】实现网络图片保存到手机相册

【问题描述】 给定一个网络图片的地址&#xff0c;实现将图片保存到手机相册 【API】 phAccessHelper.showAssetsCreationDialog【官方文档】 https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-photoaccesshelper-V5#showassetscreationdialog…

【FastAPI】离线使用Swagger UI 或 国内网络如何快速加载Swagger UI

在FastAPI中&#xff0c;默认情况下&#xff0c;当应用启动时&#xff0c;Swagger UI 会通过在线加载 Swagger UI 的静态资源。这意味着如果应用运行在没有互联网连接的环境中&#xff0c;默认的 Swagger 文档页面将无法加载。 为了在离线环境中使用 Swagger UI&#xff0c;你…

二分思想与相关例题(上)

在上一篇浅谈二分思想中&#xff0c;我们谈到了提过二分的本质&#xff0c;其实就是不断折半&#xff0c;折到最后折无可折的那个结果就是最符合要求的结果。 现在我们从答案出发&#xff0c;对答案的整体可能范围不断二分&#xff0c;最后找到最合适的答案。我们称这种方法为…

Visual Studio安装教程

这次我给大家讲一下Visual Studio安装 一、官网下载 官网下载地址&#xff1a;https://visualstudio.microsoft.com/zh-hans/downloads/ 下载下来的是一个.exe文件 双击打开&#xff0c;出现下面的界面 二、安装visual studio &#xff08;一&#xff09;更改安装路径 首先&am…