赞
踩
学习来源:b站https://www.bilibili.com/video/BV1rp4y1t7Ks?p=1
1.引入依赖
<!-- 生成方式 -->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.19.2</version>
</dependency>
<!-- 加密算法 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2.生成token
Service
@Override
public ResultVO checkLogin(String name, String password) {
Example example = new Example(Users.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("username", name);
List<Users> users = usersMapper.selectByExample(example);
if (users.size() == 0) {
return new ResultVO(ResultStatus.NO, "登录失败,用户名不存在!", null);
}else {
String md5Pwd = MD5Utils.md5(password);
if (md5Pwd.equals(users.get(0).getPassword())){
//如果登录验证成功,则需要生成令牌token(token就是按照特定规则生成的字符串)
//使用jwt规则生成token字符串,支持链式调用
JwtBuilder builder = Jwts.builder();
HashMap<String,Object> map = new HashMap<>();
map.put("key1","value1");
map.put("key2","value2");
String token = builder.setSubject(name) //主题,就是token中携带的数据
.setIssuedAt(new Date()) //设置token的生成时间
.setId(users.get(0).getUserId() + "") //设置用户id为token id,需要字符串类型
.setClaims(map) //map中可以存放用户的角色权限信息
.setExpiration(new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000)) //设置过期时间,拿到系统时间,再往后推迟一天
.signWith(SignatureAlgorithm.HS256, "Mordle") //设置加密方式和加密密码
.compact(); //设置为字符串 成为token
return new ResultVO(ResultStatus.OK, token,users.get(0));
}else {
return new ResultVO(ResultStatus.NO, "登录失败,密码错误!", null);
}
}
}
3.存储token到cookie
login.html
doSubmit:function(){
if(vm.isRight){
var url=baseUrl+"user/login";
axios.get(url,{
params:{
username:vm.username,
password:vm.password
}
})
.then((res)=>{
//res.data才表示返回的数据
var vo=res.data;
if(vo.code==10000){
//如果登录成功,就把token存到cookie中
setCookieValue("token",vo.msg);
window.location.href="index.html";
}else{
vm.tips="登录失败,账号或密码错误";
}
});
}else{
vm.tips="请正确输入账号和密码!";
}
4.解析token
Controller
public class ShopCartController {
@ApiOperation("购物车列表接口")
@ApiImplicitParam(dataType = "string",name = "token",value = "用户令牌",required = true)
@GetMapping("/list")
public ResultVO listCarts(String token){
//1.获取token
if (token==null){
return new ResultVO(ResultStatus.NO,"请先登录",null);
}else {
2.校验token,对token进行解码
JwtParser parser = Jwts.parser();
parser.setSigningKey("Mordle"); //解析token的SignKey必须和生成token时的密码一致
//如果token正确(密码正确,有效期内)则正常执行,否则抛出异常
try {
//token校验成功
Jws<Claims> claimsJws = parser.parseClaimsJws(token);
Claims body = claimsJws.getBody();//获取token中用户数据
String v1 = body.get("key1", String.class);//获取生成token时存储的map中的值
String subject = body.getSubject();//获取生成token设置的subject
return new ResultVO(ResultStatus.OK,"success",null);
}catch (Exception exception){
return new ResultVO(ResultStatus.NO,"登录过期,请先登录!",null);
}
}
}
}
5.获取token
权限页面
<script type="text/javascript">
var baseUrl="http://localhost:8080/";
var vm=new Vue({
el:'#container',
data:{
token:"",
shopcarts:[]
},
created:function(){
//当进入购物车页面时候,就要查询购物城列表(访问购物车列表接口)
this.token=getCookieValue("token");
var url=baseUrl+"shopcart/list";
axios.get(url,{params:{
token:this.token
}}).then((res)=>{
var vo=res.data;
console.log(vo);
});
}
});
</script>
就是把controller里的进行封装
package com.mordle.mall.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mordle.mall.vo.ResultStatus;
import com.mordle.mall.vo.ResultVO;
import io.jsonwebtoken.*;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/*拦截器*/
@Component
public class CheckTokenInterceptor implements HandlerInterceptor {
/*前置拦截*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token=request.getParameter("token");
if(token==null){
ResultVO resultVO = new ResultVO(ResultStatus.NO, "请先登录", null);
doResponse(response,resultVO);
}else{
try {
2.校验token,对token进行解码
JwtParser parser = Jwts.parser();
parser.setSigningKey("Mordle"); //解析token的SignKey必须和生成token时的密码一致
//如果token正确(密码正确,有效期内)则正常执行,否则抛出异常
//token校验成功
Jws<Claims> claimsJws = parser.parseClaimsJws(token);
return true;
}catch (ExpiredJwtException e){
ResultVO vo = new ResultVO(ResultStatus.NO, "登录过期,请重新登录!", null);
doResponse(response,vo);
}catch (UnsupportedJwtException exception){
ResultVO vo = new ResultVO(ResultStatus.NO,"Token不合法,请自重!",null);
doResponse(response,vo);
}catch (Exception exception){
ResultVO vo = new ResultVO(ResultStatus.NO,"请重新登录!",null);
doResponse(response,vo);
}
}
return false;
}
private void doResponse(HttpServletResponse response,ResultVO resultVO) throws IOException {
//提示请先登录
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
String s = new ObjectMapper().writeValueAsString(resultVO);
out.print(s);
out.flush();
out.close();
}
}
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
private CheckTokenInterceptor checkTokenInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(checkTokenInterceptor)
.addPathPatterns("/shopcart/**") //拦截受限资源
.addPathPatterns("/orders/**")
.excludePathPatterns("/user/**"); //除了user开头
}
}
@RestController
@RequestMapping("/shopcart")
@CrossOrigin
@Api(value = "提供购物车相关接口",tags = "购物车管理")
public class ShopCartController {
@ApiOperation("购物车列表接口")
@ApiImplicitParam(dataType = "string",name = "token",value = "用户令牌",required = true)
@GetMapping("/list")
public ResultVO listCarts(String token){
return new ResultVO(ResultStatus.OK,"success",null);
}
}
前端访问受限资源必须携带token进行请求,习惯性用header传递
并且把后端接收方式改了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。