素材巴巴 > 程序开发 >

SpringBoot Vue token实现登录拦截 前后端分离

程序开发 2023-09-11 12:03:42

这个是我工作中遇到的一个问题,因为之前没用过token,所以很陌生。不过好在我在网上一顿查,CSDN和度娘都快被我翻没了终于把他整出来了,现在来看一下代码。

首先先看一下我们用到得类有哪些。我们主要用到的是这几个类。

首先我们需要整一个TokenUtil的工具类

TokenUtil(工具类)

这里面的东西你基本上复制一下就可以不需要改什么东西,只需要改一下你的参数就可以了。

package com.wl.util;import com.auth0.jwt.JWT;
 import com.auth0.jwt.JWTVerifier;
 import com.auth0.jwt.algorithms.Algorithm;
 import com.auth0.jwt.interfaces.DecodedJWT;
 import java.util.*;/*** @author 小于小于, 一条咸鱼* @date 2022/6/17 13:37*/
 public class TokenUtil {/*** 过期时间为一个小时*/private static final long EXPIRE_TIME =  60 * 60 * 1000;/*** token私钥  这里的密码随便写就可以*/private static final String TOKEN_SECRET = "adm2345dfin234sdsdff";/**这里的参数根据你的需要来,因为我没有实体类,所以我在登录接口中写的假数据,这里你如果有实体类 的话你可以传一个User user*/public static String createToken(String username,String password) {String token = null;Date expiration = new Date(System.currentTimeMillis() + EXPIRE_TIME);Map header = new HashMap<>();header.put("typ","JWT");header.put("alg","HS256");token = JWT.create().withIssuer("auth0").withHeader(header)//这个地方是你传的参数.withClaim("username",username).withClaim("password",password).withExpiresAt(expiration).sign(Algorithm.HMAC256(TOKEN_SECRET));return token;}public static boolean verify(String token) {try {JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();DecodedJWT jwt = verifier.verify(token);System.out.println("认证通过:");System.out.println("过期时间:" + jwt.getExpiresAt());return true;} catch (Exception e) {e.printStackTrace();System.out.println("Token认证失败,需要重新登录!");}return false;}
 }
 

接下来我们需要创建一个拦截器

创建拦截器(TokenInterceptor)

这里也不需要改很多东西直接,就是要改一下前端Vue的显示token的字段。

package com.wl.config;import com.wl.util.TokenUtil;
 import org.json.JSONObject;
 import org.springframework.stereotype.Component;
 import org.springframework.web.bind.annotation.CrossOrigin;
 import org.springframework.web.servlet.HandlerInterceptor;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;/*** @author 小于小于, 一条咸鱼* @date 2022/6/20 17:27*/
 @Component
 @CrossOrigin
 public class TokenInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception{if(request.getMethod().equals("OPTIONS")){response.setStatus(HttpServletResponse.SC_OK);return true;}response.setCharacterEncoding("UTF-8");//这里是前端Vue放在请求头中的字段名   Authorization:token字符串String token = request.getHeader("Authorization");if (token != null){boolean flag = TokenUtil.verify(token);if (flag) {System.out.println("验证成功:"+ token);return true;}}response.setCharacterEncoding("UTF-8");response.setContentType("application/json; charset=utf-8");try{JSONObject json = new JSONObject();json.put("msg","token失效请重新登陆");json.put("code","50000");response.getWriter().append(json.toString());System.out.println("认证失败,未通过拦截器");}catch (Exception e){e.printStackTrace();response.sendError(500);return false;}return false;}
 }
 

 配置跨域

这里的话也不需要改很多,只需要改一下你要拦截的路径即可,我是因为没有注册,我只把登录的接口给放出来了,其他的接口全部拦截。你可以根据的你的需要进行取舍,这里得线城池我是手动创建的,具体啥用我也没太搞懂,有没有这个应该是都可以的,你要嫌麻烦直接copy是没问题的。是

package com.wl.config;import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
 import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
 import org.springframework.web.servlet.config.annotation.CorsRegistry;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.*;
 import java.util.concurrent.ThreadPoolExecutor;/*** @author 小于小于, 一条咸鱼* @date 2022/6/20 17:57*/
 @Configuration
 public class WebMvcConfig implements WebMvcConfigurer {//最大30线程,外加30队列;【拒绝策略AbortPolicy(默认): 丢弃任务并抛出异常】private static ExecutorService executorService = new ThreadPoolExecutor(1, 30, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3));@Autowiredprivate TokenInterceptor tokenInterceptor;@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedHeaders("*").allowedMethods("*").allowedOriginPatterns("*").allowCredentials(true);}@Overridepublic void configureAsyncSupport(AsyncSupportConfigurer configurer) {configurer.setTaskExecutor(new ConcurrentTaskExecutor(executorService));configurer.setDefaultTimeout(30000);}@Overridepublic void addInterceptors(InterceptorRegistry registry) {List excludePath = new ArrayList<>();//排除拦截,除了注册登录(此时还没token),其他都拦截excludePath.add("/user/login");  //登录//excludePath.add("/login");     //注册//excludePath.add("/assets");  //静态资源//excludePath.add("/song/**");  //静态资源registry.addInterceptor(tokenInterceptor).addPathPatterns("/**").excludePathPatterns(excludePath);WebMvcConfigurer.super.addInterceptors(registry);}}
 

 最后就是我们的登录接口了

LoginController

这里就很简单了,判断前端的账号密码是否正确,正确的话就创建Token然后保存在map中并返回给前端,如果不正确就给前端一个500的错误提示。

package com.wl.conrtoller;import com.wl.util.TokenUtil;
 import org.springframework.web.bind.annotation.*;
 import java.util.HashMap;
 import java.util.Map;/*** @author 小于小于, 一条咸鱼* @date 2022/6/17 13:05*/
 @ResponseBody
 @RestController
 @CrossOrigin
 @RequestMapping(value = "/user")
 public class LoginController {/*** 登录** @param* @return*      192.168.124.39:8081/user/login*/@PostMapping("/login")public Object login(@RequestParam("username") String username,@RequestParam("password") String password){Map map = new HashMap<>();if ("admin".equals(username)&& "123456".equals(password)){//创建token并返回给前端。String token = TokenUtil.createToken(username, password);map.put("token",token);map.put("username",username);map.put("password",password);map.put("msg","登录成功");map.put("code",200);}else {map.put("msg","账号密码错误");map.put("code",500);}return map;}}


标签:

上一篇: JAVAweb中JavaScript常见技巧总结 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。