登录校验的实现思路是怎样的?
实现思路:可以在访问资源前进行访问的拦截,判断你当前会话是否有登录,如果没有登录拒绝访问。如果是登录的那就可以进行访问资源。
会话技术有哪些方式可以实现?
传统技术可以使用Cookie+Session去实现会话,进行会话跟踪。但是这种传统方式有弊端:不能在集群服务中灵活使用,手机客户端无法支持Cookie。
为了解决这些问题,可以使用令牌技术来解决。令牌技术优点是:可以在集群服务中灵活使用,移动端也可以支持。
JWT令牌组成部分有哪些,各自作用是什么?
三部分组成:
header.payload.signature
header.payload.signature 部分的数据会以Base64的方式进行编译。
这三部分的作用分别是:
header:指定令牌类型,加密的算法...
payload:存储一些令牌要携带的信息,比如用户的基本信息id,username, 过期时间
signature :保证令牌不被篡改。
怎么使用JWT令牌?(依赖,创建,校验)
1). pom.xml 引入jwt的依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2). 创建令牌
public class JwtDemo {
@Test
public void genJwt(){
Map<String,Object> claims = new HashMap<>();
claims.put("id",1);
claims.put("username","Tom");
String jwt = Jwts.builder()
.setClaims(claims) //执行第二部分负载, 存储的数据
.signWith(SignatureAlgorithm.HS256, "itheima") //签名算法及秘钥
.setExpiration(new Date(System.currentTimeMillis() + 12*3600*1000)) //设置令牌的有效期
.compact();
System.out.println(jwt);
}
}
3).解析令牌
@Test
public void parseJwt(){
Claims claims = Jwts.parser()
.setSigningKey("itheima")
.parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwiZXhwIjoxNjU5OTk1NTE3LCJ1c2VybmFtZSI6IlRvbSJ9.EUTfeqPkGslekdKBezcWCe7a7xbcIIwB1MXlIccTMwo")
.getBody();
System.out.println(claims);
}
当解析不报异常,此时就代表令牌是有效的。报任何异常都意味着令牌失效
项目中在什么时候去生成令牌?
在登录成功之后,生成JWT令牌并返回给浏览器。
当前端携带令牌访问资源时怎么去拦截校验令牌的合法性?
需要做的就是需要在服务端统一拦截校验JWT令牌。
那统一拦截请求,在服务端,我们可以通过两种手段实现:过滤器Filter、拦截器Interceptor。
过滤器具体使用的步骤是怎样的?
Filter使用步骤如下:
1、创建一个类实现接口Filter接口,重写doFilter方法
2、类上面需要加注解:@WebFilter(urlPatterns = "/*")
3、在引导类中注解:@ServletComponentScan
4、要做具体的拦截业务在doFilter中完成
public void doFilter(ServletRequest req, ServletResponse rsp, FilterChain chain) {
//登录校验拦截
xxxxxx
//放行(如果不放行,就不执行如下语句)
chain.doFilter(req,rsp);
yyyyyyy
}
拦截器具体使用的步骤是怎样的?
Interceptor使用步骤如下:
1、创建一个类实现HandlerInterceptor接口,上面加上注解@Component
public class LoginCheckInterceptor implements HandlerInterceptor
2、重写方法
preHandler 方法可以实现在资源访问前的拦截
3、写配置类,在里面进行注册:
3.1 写一个类叫做配置,实现接口WebMvcConfigurer,并在类型上加上注解:@Configuration
@Configuration
public class WebConfig implements WebMvcConfigurer
3.2 注入拦截器对象,重写方法addInterceptors 进行注册,并设定拦截路径。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginCheckInterceptor loginCheckInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册拦截器
registry.addInterceptor(loginCheckInterceptor)
.addPathPatterns("/**");
}
}
项目中异常是怎么处理的?具体怎么实现?
异常处理有两种方案:
1、在每一个Controller中的方法里面单独try-catch捕获处理(代码冗余,繁琐)
2、全局异常处理(推荐的方案)
全局异常处理的实现步骤:
1、创建一个类用来专门处理异常,在类上面加上注解:@RestControllerAdvice
2、在里面写一个方法用来处理异常:该方法返回值类型用同一响应结果Result,还需要使用注解@ExceptionHandler 去定义要处理的异常类型。
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* Exception异常分类
* - 运行时异常 : RuntimeException , 编译时无需处理 .
* - 编译时异常 : 非 RuntimeException , 编译时处理 .
*/
@ExceptionHandler(Exception.class)
public Result ex(Exception ex){
ex.printStackTrace();
return Result.error("系统繁忙, 请稍后重试 ... ");
}
}