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