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:本文就写到这里了,谢谢观看