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 + '">查看全文>></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:本文就写到这里了,谢谢观看



















