感谢分享 代码来源: springboot项目整合token,实现项目的认证与授权(提供代码)_springboot整合token_一写代码就开心的博客-CSDN博客
目录
目录
1.概述
2. 实现步骤
2.1 maven引入相关包
2.2 建立辅助类
2.3 定义拦截器
2.4 controller编写
2.5 注册拦截器
3. 测试验证
3.1 不登录,直接调用getUserList请求
3.2 登录获取token值
3.3 再来调用getUserList
4. 结语
经常写http、https请求的程序开发,经常碰到三方都有一个token(令牌)的授权与验证,感觉这个功能很好用,借此学习SpingBoot的机会,在网上去找了一篇相关的文章,进行实际操作下。我原本以为token是生成后会保存到数据库去,其实不然,可能场景不同,实际也会有点差别。
22年底时候,当时对接社会化信息、公安信息、实名就诊信息等接口时候,都用到了这个。通过注册或服务直接分配,得到一个账号。通过授权(登录)获得一个token,这个token是有时间限制的,比如2个小时,然后才可以调用服务的接口。2个小时后,需要重新授权(登录)。
在pom.xml文件,加入依赖。
com.auth0
java-jwt
3.10.3
这个辅助类提供token生成与验证功能。额外写一个test()方法,加入了@Test注解,进行单元测试操作。
public class JwtUtils {
public static String SECRET= "1c2h3e4n5w6e7i8x9i0n";
public static String getToken(Map map){
JWTCreator.Builder builder= JWT.create();
map.forEach((k,v)->{
builder.withClaim(k,v);
});
Calendar instance= Calendar.getInstance();
instance.add(Calendar.HOUR, 2); //默认2小时过期
builder.withExpiresAt(instance.getTime());
String token= builder.sign(Algorithm.HMAC256(SECRET));
return token;
}
public static DecodedJWT verfy(String token){
DecodedJWT decodedJWT= JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
return decodedJWT;
}
@Test
public void test() {
Map map=new HashMap<>();
map.put("username", "1107230602");
map.put("password", "0246813579");
String token= JwtUtils.getToken(map);
}
}
拦截器的作用主要是完成请求参数的解析、将页面表单参数赋给值栈中相应属性、执行功能检验、程序异常调试等工作。此处拦截的功能是对token进行校验.
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token= request.getHeader("token");
Map map= new HashMap<>();
if (token== null || token.trim().equals("")){
map.put("message", "无token值!");
} else{
try{
JwtUtils.verfy(token);
return true;
} catch (SignatureVerificationException e){
e.printStackTrace();
map.put("message", "签名不一致!");
} catch (TokenExpiredException e){
e.printStackTrace();
map.put("message","令牌过期!");
} catch (AlgorithmMismatchException e){
e.printStackTrace();
map.put("message", "算法不匹配!");
} catch (InvalidClaimException e){
e.printStackTrace();
map.put("message","失效payload!");
} catch (Exception e){
e.printStackTrace();
map.put("message","token无效");
}
}
map.put("state", false);
String json= new ObjectMapper().writeValueAsString(map);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
return false;
}
}
我在UserController中添加了一个获取用户列表、登录两个功能。在登录方法中,实现token的获取并返回。该方法仅仅用于举例说明。在这个controller的类抬头,我还加入了@RequestMapping,所以,接口调用地址是".../api/user/getUserList"和".../api/user/login"
@RequestMapping("/api")
/**
* 查询所有数据
* @return
*/
@GetMapping("/user/getUserList")
public Result> getUserList(){
List userList= null;
SqlSession sqlSession= null;
try{
sqlSession= MybatisUtils.getSqlSession();
//Mapper代理开发
UserMapper mapper= sqlSession.getMapper(UserMapper.class);
userList= mapper.getUserList();
} catch (Exception e){
e.printStackTrace();
} finally {
if (sqlSession!= null) {
sqlSession.close();
}
}
return Result.ok(userList);
}
/**
* 登录验证
* @return
*/
@PostMapping("/user/login")
public Result> login(@RequestBody User user){
SqlSession sqlSession= null;
Map map= new HashMap<>();
try{
sqlSession= MybatisUtils.getSqlSession();
UserMapper mapper= sqlSession.getMapper(UserMapper.class);
user= mapper.login(user);
if (user!= null){
//生成token
Map tokenmap= new HashMap<>();
tokenmap.put("username", user.getUsername());
tokenmap.put("password", user.getPassword());
String token= JwtUtils.getToken(tokenmap);
//返回数据
map.put("user", user);
map.put("token", token);
return Result.ok(map);
} else {
return Result.error(CommonConstant.SYS_ERR_CODE, "用户不存在!");
}
} catch (Exception e){
e.printStackTrace();
return Result.error("异常!"+ e.getMessage());
} finally {
if (sqlSession!= null){
sqlSession.close();
}
}
}
在2.3中定义了拦截器,通过注册,启动拦截器功能。addPathPatterns()方法是只将哪些api纳入拦截范围。excludePathPatterns()方法是排除哪些,二者功能相反。像登录操作,肯定是不需要进行token验证的,就排除在外了。
@Configuration
public class JwtInterceptorConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JwtInterceptor())
.addPathPatterns("/api/user/**")
.excludePathPatterns("/api/user/login");
}
}
token的授权和验证,在web服务中是一种很常见的用法。
仅供参考.