从零开始的SpringBoot前后端分离入门级项目(三)

这是一个目录
实体类编写利用Token进行用户鉴权创建Jwt工具类利用拦截器(interceptor)实现用户访问的拦截与鉴权编写InterceptorConfig

实体类编写

在前面的文章中我们已经完成了项目目录和基本框架的搭建,现在我们开始编写实体类,首先我们在model包下创建一个pojo子包。
注意:关于PO、VO、POJO、DTO等概念网络上已经有很多资料了,在本项目中不再阐述其的详细含义,且为了方便起见只划分POJO与DTO,为此产生的一些有歧义或错误的划分方法或用法请读者们见谅。
创建好子包之后我们创建相应的pojo,一张表对应一个类,如果编写过Web项目的同学对这步应该是比较熟悉的,创建相应的类的过程笔者不一一讲解,具体可以参见笔者的GitHub主页,后续将会上传完整的直接导入的工程代码,创建完毕后请务必将@Data、@AllArgsConstructor、@NoArgsConstructor三个注解加上。
从零开始的SpringBoot前后端分离入门级项目(三)

利用Token进行用户鉴权

实体类编写完之后我们开始进行用户权限认证功能的编写,在本项目中利用了jwt和拦截器(interceptor)进行实现。
首先在本项目仅分为三种角色:

    实验室管理员(ADMIN)实验室成员(VIP)普通用户(MEMBER)

这种划分方式是不够严谨和安全的,目前的权限划分一般是分为用户角色和用户权限两个部分,每个用户对应某个角色,某个角色拥有某些权限,欢迎读者自行思考更完善的权限划分方案。

创建Jwt工具类

首先我们先前往util包中创建一个名为JwtUtil的类,类的内容如下:
JwtUtil

/**
* @Author Alfalfa99
* @Date 2020/9/13 15:54
* @Version 1.0
* JWT生成以及校验工具类
*/

@ConfigurationProperties("jwt.config")
@Component
public class JwtUtil {
private String key;
private long ttl;

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public long getTtl() {
return ttl;
}

public void setTtl(long ttl) {
this.ttl = ttl;
}

/**
* 生成JWT
*
* @param id
* @return
*/
public String createJWT(String id, String roles) {
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
JwtBuilder builder = Jwts.builder().setId(id) //在这里我们将用户的id存入Jwt中,方便后续使用
.setIssuedAt(now)
.signWith(SignatureAlgorithm.HS256, key).claim("roles", roles); //在这里我们将用户的角色存入Jwt中,方便后续鉴权,如果想存别的内容也可以往里写
if (ttl > 0) {
builder.setExpiration(new Date(nowMillis + ttl));
}
return builder.compact();
}

/**
* 解析JWT
*
* @param jwtStr
* @return
*/
public Claims parseJWT(String jwtStr) {
return Jwts.parser()
.setSigningKey(key)
.parseClaimsJws(jwtStr)
.getBody();
}
}

key是服务端用于加密的一个密文,通常随机生成,ttl是token的过期时间,token的详细原理请自行查阅学习,篇幅有限不再赘述。在这里我们利用了@ConfigurationProperties("jwt.config")注解从application.yml配置文件中读取了如下配置并自动注入字段

jwt:
config:
key: SecretKey #服务端加密所使用的密文(自拟)
ttl: 21600000 #毫秒
#请将该段复制至application.yml以便于能够启动项目

回到token,token是用户在成功登录后读取用户的角色和id生成得来的,生成的token应该在登陆成功后返回给前端,前端之后每次访问接口都应该带上这个token。
注意:千万不要使用token存储用户的敏感信息,token只能用于避免被篡改,而不用于加密!token本身携带的内容是可以在没有服务端秘钥的情况下直接解析出来的!!!
这时候我们就可以实例化JwtUtil并使用createJWT生成token或者使用parseJWT解析token了

利用拦截器(interceptor)实现用户访问的拦截与鉴权

在上文中我们已经能够解析与生成一个token了,但是如果我们在每一个接口都重新解析token进行权限认证将过于繁琐且损耗服务器性能,如果之前有过JavaEE项目编写经验的读者应该学习过过滤器(Filter),拦截器是Spring框架为我们提供的一种类似于Filter的组件但拦截器的功能更多更强劲,话不多说直接怼代码,首先我们在主启动类的同级目录创建一个interceptor包用于存放我们的拦截器,并在这个包下创建一个名为Tokeninterceptor的类,类的内容:

/**
* @Author Alfalfa99
* @Date 2020/9/13 18:18
* @Version 1.0
* 全局校验Token
*/
@Component
public class TokenInterceptor implements HandlerInterceptor {

private final JwtUtil jwtUtil;

public TokenInterceptor(JwtUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}

/**
* 通过拦截器对请求头进行校验
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String header = request.getHeader("Authorization");
if (header != null && !"".equals(header)) {
if (header.startsWith("Bearer ")) {
//获得token
String token = header.substring(7);
//验证token
try {
Claims claims = jwtUtil.parseJWT(token);
String roles = (String) claims.get("roles");
if (roles != null) {
request.setAttribute("uid",claims.getId());
request.setAttribute("roles",roles);
return true;
} else {
throw new BadCredentialsException("令牌已失效");
}
} catch (Exception e) {
throw new BadCredentialsException("令牌已失效");
}
}
}
throw new AuthenticationCredentialsNotFoundException("请先登录");
}
}

前端每次请求时token应该是放置于请求头中键名为Authorization, 值为Bearer Token(Token为服务端生成的token)。

首先我们使用@Component注解将该类注册为一个Spring容器,然后使用该类实现 HandlerInterceptor接口,preHandle说明我们是在目标方法执行前进行处理。我们先通过构造器的方式将JwtUtil注入便于后续使用,然后从请求头中读取token,如果token为空则说明用户没有登陆,直接抛出异常即可,如果在解析token出现错误直接抛出错误即可。这一个部分的主要思路就是如果不能正确的解析出token的内容则返回给前端错误信息,让前端跳转到登录页面进行重新登录,如果能够正确解析出我们存储的用户id和用户角色这两个内容则添加到请求request域里面去,后续我们在接口处的直接可以从request中读到用户iduid和用户角色roles
这样我们就可以判断每次访问时用户是否已经登陆了,并且我们将用户id以及用户角色都存于request中便于我们之后controller的开发。

编写InterceptorConfig

在完成TokenInterceptor类的编写之后我们关于Token鉴权的内容就基本结束了,当然我们还需要编写一个InterceptorConfig类去配置我们的拦截器,那么我们在config包中创建一个名为InterceptorConfig的类,类的内容如下:

/**
* @author 苜蓿
* @date 2020/9/13
* 拦截器配置类
*/
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {

private final TokenInterceptor tokenInterceptor;

public InterceptorConfig(TokenInterceptor tokenInterceptor) {
this.tokenInterceptor = tokenInterceptor;
}

@Override
protected void addInterceptors(InterceptorRegistry registry) {
//拦截所有目录,除了通向login和register的接口
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/**/login/**", "/**/register/**")
.excludePathPatterns("/**/*.html", "/**/*.js", "/**/*.css");
}

那么我们的TokenInterceptor就已经配置完成了,拦截除了html文件、css文件、js文件以及登录注册接口之外的所有访问请求并进行鉴权。

那么本篇博客的内容也已经完成了,在下一篇博客我们就开始进入controller的编写。

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

从零开始的SpringBoot前后端分离入门级项目(三)

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » 从零开始的SpringBoot前后端分离入门级项目(三)
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏