建设银行光明支行网站,网站功能模块什么意思,总算把网站设计好了,学校网站建设制度第4章-第4节
一、知识点
CSRF、token、JWT
二、目标 理解什么是CSRF攻击以及如何防范 理解什么是token 理解什么是JWT 理解session验证和JWT验证的区别 学会使用JWT
三、内容分析 重点 理解什么是CSRF攻击以及如何防范 理解什么是token 理解什么是JWT 理解session验…第4章-第4节
一、知识点
CSRF、token、JWT
二、目标 理解什么是CSRF攻击以及如何防范 理解什么是token 理解什么是JWT 理解session验证和JWT验证的区别 学会使用JWT
三、内容分析 重点 理解什么是CSRF攻击以及如何防范 理解什么是token 理解什么是JWT 理解session验证和JWT验证的区别 学会使用JWT 难点 理解session验证和JWT验证的区别 学会使用JWT
四、内容
1、CSRF
1.1 概述
CSRF全称为跨站请求伪造Cross-site request forgery是一种网络攻击方式也被称为 one-click attack 或者 session riding。
1.2 原理
CSRF攻击利用网站对于用户网页浏览器的信任挟持用户当前已登陆的Web应用程序去执行并非用户本意的操作。网站是通过cookie来实现登录功能的而cookie只要存在浏览器中那么浏览器在访问这个cookie的服务器的时候就会自动的携带cookie信息到服务器上去。那么这时候就存在一个漏洞了如果你访问了一个别有用心或病毒网站这个网站可以在网页源代码中插入js代码使用js代码给其他服务器发送请求比如ICBC的转账请求。那么因为在发送请求的时候浏览器会自动的把cookie发送给对应的服务器这时候相应的服务器比如ICBC网站就不知道这个请求是伪造的就被欺骗过去了。从而达到在用户不知情的情况下给某个服务器发送了一个请求比如转账。 1.3 解决方案
CSRF攻击的要点就是在向服务器发送请求的时候相应的cookie会自动的发送给对应的服务器。造成服务器不知道这个请求是用户发起的还是伪造的。这时候我们可以在用户每次访问有表单的页面的时候在网页源代码中加一个随机的字符串叫做csrf_token在cookie中也加入一个相同值的csrf_token字符串。以后给服务器发送请求的时候必须在body中以及cookie中都携带csrf_token服务器只有检测到cookie中的csrf_token和body中的csrf_token都相同才认为这个请求是正常的否则就是伪造的。那么黑客就没办法伪造请求了。
2、JWT
2.1 什么是token
Token在计算机身份认证中是令牌临时的意思在词法分析中是标记的意思。一般作为邀请、登录系统使用。
2.2 什么是JWT
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准(RFC 7519).定义了一种简洁的自包含的方法用于通信双方之间以JSON对象的形式安全的传递信息。因为数字签名的存在这些信息是可信的JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。
2.3 JWT的请求流程 用户使用账号和面发出登录请求 服务器验证并创建一个jwt 服务器返回这个jwt给浏览器 浏览器将该jwt串在请求头中向服务器发送请求 服务器验证该jwt 返回响应的资源给浏览器
2.4 为什么使用JWT
2.4.1 传统Session认证的弊端
在用户首次登录成功后在服务器存储一份用户登录的信息(session)这份登录信息会在响应时传递给浏览器告诉其保存为cookie以便下次请求时发送给我们的应用这样我们的应用就能识别请求来自哪个用户了这是传统的基于session认证的过程。
然而传统的session认证有如下的问题 每个用户的登录信息都会保存到服务器的session中随着用户的增多服务器开销会明显增大 对于非浏览器的客户端、手机移动端等不适用因为session依赖于cookie而移动端经常没有cookie 因为session认证本质基于cookie所以如果cookie被截获用户很容易收到跨站请求伪造攻击。并且如果浏览器禁用了cookie这种方式也会失效 由于基于Cookie而cookie无法跨域所以session的认证也无法跨域对单点登录不适用
2.4.2 JWT认证的优势 JWT Token数据量小传输速度也很快 因为JWT Token是以JSON加密形式保存在客户端的所以JWT是跨语言的原则上任何web形式都支持 不需要在服务端保存会话信息也就是说不依赖于cookie和session所以没有了传统session认证的弊端 单点登录友好使用Session进行身份认证的话由于cookie无法跨域难以实现单点登录。但是使用token进行认证的话 token可以被保存在客户端的任意位置的内存中不一定是cookie所以不依赖cookie不会存在这些问题 适合移动端应用使用Session进行身份认证的话需要保存一份信息在服务器端而且这种方式会依赖到Cookie需要 Cookie 保存 SessionId所以不适合移动端
身份认证在这种场景下一旦用户完成了登陆在接下来的每个请求中包含JWT可以用来验证用户身份以及对路由服务和资源的访问权限进行验证。由于它的开销非常小可以轻松的在不同域名的系统中传递。 信息交换在通信的双方之间使用JWT对数据进行编码是一种非常安全的方式由于它的信息是经过签名的可以确保发送者发送的信息是没有经过伪造的。
2.4 JWT结构
JWT由3部分组成标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候会将JWT的3部分分别进行Base64编码后用.进行连接形成最终传输的字符串 2.5.1 Header
JWT头是一个描述JWT元数据的JSON对象alg属性表示签名使用的算法默认为HMAC SHA256写为HS256
2.5.2 Payload
有效载荷部分是JWT的主体内容部分也是一个JSON对象包含需要传递的数据。 默认情况下JWT是未加密的因为只是采用base64算法拿到JWT字符串后可以转换回原本的JSON数据任何人都可以解读其内容因此不要构建隐私信息字段比如用户的密码一定不能保存到JWT中以防止信息泄露。JWT只是适合在网络中传输一些非敏感的信息 2.5.3 Signature
签名部分是对上面两部分数据签名需要使用base64编码后的header和payload数据通过指定的算法生成哈希以确保数据不会被篡改。首先需要指定一个密钥secret。该密钥仅仅为保存在服务器中并且不能向用户公开。然后使用header中指定的签名算法默认情况下为HMAC SHA256根据以下公式生成签名
3、SpringBoot使用JWT
3.1 添加jwt依赖
dependencygroupIdcom.auth0/groupIdartifactIdjava-jwt/artifactIdversion3.4.0/version
/dependency
3.2 封装工具类 封装返回值的类 Data
AllArgsConstructor
NoArgsConstructor
public class AjaxResultT {private Integer code;private String msg;private T data;
/*** 成功的返回结果** param msg 成功信息* param data 返回的值* param T 返回值的泛型* return 返回AjaxResult对象*/public static T AjaxResultT success(String msg, T data) {return new AjaxResultT(200, msg, data);}
/*** 成功的返回结果** param data 返回的值* param T 返回值的泛型* return 返回AjaxResult对象*/public static T AjaxResultT success(T data) {return new AjaxResultT(200, 操作成功, data);}
/*** 失败的返回结果** param msg 成功信息* param data 返回的值* param T 返回值的泛型* return 返回AjaxResult对象*/public static T AjaxResultT error(String msg, T data) {return new AjaxResultT(500, msg, data);}
/*** 失败的返回结果** param data 返回的值* param T 返回值的泛型* return 返回AjaxResult对象*/public static T AjaxResultT error(T data) {return new AjaxResultT(500, 操作失败, data);}
/*** 认证失败的返回结果** param msg 成功信息* param data 返回的值* param T 返回值的泛型* return 返回AjaxResult对象*/public static T AjaxResultT unAuth(String msg, T data) {return new AjaxResultT(401, msg, data);}
} 将jwt的验证等功能封装一下方便后续调用 public class JWTUtil {// 加密的秘钥封装一下private static final String SECRET secret;// id字段private static final String ID_FIELD userID;// token的有效时间 30 天private static final Integer TIME_OUT_DAY 30;
/*** 创建token** param user 登陆的用户* return 返回Token字符串*/public static String createToken(SysUser user) {// 获取日历对象实例Calendar calendar Calendar.getInstance();// 在当前日期加上 TIME_OUT_DAY 的时间用于设置过期时间calendar.add(Calendar.DATE, TIME_OUT_DAY);System.out.println(user.getId());// 创建jwtreturn JWT.create()// 可以在token中设置数据,设置一个userId为用户的id// 后续可以直接在token中获取id.withClaim(ID_FIELD, user.getId())// 设置token过期时间.withExpiresAt(calendar.getTime())// Algorithm.HMAC256(SECRET) 使用HMAC256的加密方式// secret 指的是秘钥在这个秘钥的基础上进行加密加大破解的难度这个秘钥爱写什么写什么.sign(Algorithm.HMAC256(SECRET));}
/*** 验证JWT返回为false的时候表示验证失败** param token token字符串* return 返回boolean 表示是否登录成功*/public static boolean verifyToken(String token) {try {// 验证JWT验证不通过会报错JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);return true;} catch (Exception e) {return false;}}
/*** 获取用户id返回值是0表示没有找到id** param token token 字符串* return 返回对应的用户id如果为0则表示没有用户*/public static Long getUserId(String token) {try {// 获取id没有id则会报错return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token).getClaim(ID_FIELD).asLong();} catch (Exception e) {// 如果报错就返回null表示没有找到对应的用户return 0L;}}
}
3.3 token创建测试 写一个登录接口进行测试控制层、持久层等代码不展示 PostMapping(/login)
public AjaxResultString login(User user) {// 添加用户的帐号密码的条件LambdaQueryWrapperUser wrapper new LambdaQueryWrapper();wrapper.eq(User::getUsername, user.getUsername());wrapper.eq(User::getPassword, user.getPassword());// 使用Mybatis-Plus查询用户User loginUser service.getOne(wrapper);// 只有登录成功才需要jwtif (loginUser null) {return AjaxResult.unAuth(登录失败, null);}String token JWTUtil.createToken(loginUser);// 登录成功后把token返回给前端return AjaxResult.success(token);
} 发现这个登录接口可以获得到生成的token说明我们的token的创建是没有问题那么验证呢 要验证接口首先要先把请求拦截下来所以需要添加拦截器 3.4 添加拦截器
3.4.1 拦截器 拦截请求验证请求头是否携带了token /*** 授权拦截器用来验证用户是否有权利访问接口*/
public class AuthInterceptor implements HandlerInterceptor {/*** 要验证用户是否有权限那么就要验证token** param request* param response* param handler* return* throws Exception*/Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 从头部获取我们的tokenString token request.getHeader(token);// 设置返回值类型response.setContentType(text/plain;charsetutf-8);// 如果token是空的就说明没有token没有权限if (token null) {response.getWriter().write(没有token);return false;}boolean b JWTUtil.verifyToken(token);if (!b) {response.getWriter().write(用户认证失败);return false;}// 统一处理用户id不存在的情况Long userId JWTUtil.getUserId(token);if (userId null) {response.getWriter().write(用户不存在或者过期);return false;}return b;}
}
3.4.2 拦截器配置
Configuration
public class AuthInterceptorConfig implements WebMvcConfigurer {Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor()).addPathPatterns(/**).excludePathPatterns(/user/login);// 登录接口是不要验证token的}
}
3.5 token验证测试
GetMapping
public AjaxResultUser getUserInfo(HttpServletRequest req) {LambdaQueryWrapperUser wrapper new LambdaQueryWrapper();// 获取TokenString token req.getHeader(token);// 获取用户IdLong id JWTUtil.getUserId(token);// 根据Id查询User loginUser service.getById(id);if (loginUser null) {return AjaxResult.error(用户不存在, null);}return AjaxResult.success(loginUser);
}
3.6 优化返回值 优化返回值改成json格式的 3.6.1 封装响应工具类ResponseUtil
public class ResponseUtil {/**** param response 响应对象* param data 要返回的对象* throws IOException*/public static void responseToWeb(HttpServletResponse response, Object data) throws IOException {ObjectMapper mapper new ObjectMapper();// 使用jackson的对象转JSON字符串String resultStr mapper.writeValueAsString(data);// 设置返回的数据类型和编码格式response.setContentType(text/plain;charsetutf-8);// 通过写出流发送给调用者response.getWriter().write(resultStr);}
}
3.6.2 直接调用修改即可
if (token null) {ResponseUtil.responseToWeb(response, AjaxResult.unAuth(没有Token, null));return false;
}
4、小结
本章节中我们学习了CSRF攻击以及如何防范、理解了什么是token、什么是JWT、学些了session验证和JWT验证的区别、同时在SpringBoot中对JWT进行了封装和使用对开发中的登录流程有了一个更加清晰的认知。
下一节中我们将会学习Redis技术了解什么是NoSql、为什么要使用NoSql、什么是Redis、Redis的优势是什么、如何使用Redis。 文章转载自: http://www.morning.chfxz.cn.gov.cn.chfxz.cn http://www.morning.ygkb.cn.gov.cn.ygkb.cn http://www.morning.trrhj.cn.gov.cn.trrhj.cn http://www.morning.xbzfz.cn.gov.cn.xbzfz.cn http://www.morning.tgxrm.cn.gov.cn.tgxrm.cn http://www.morning.hphfy.cn.gov.cn.hphfy.cn http://www.morning.lxhgj.cn.gov.cn.lxhgj.cn http://www.morning.zpxwg.cn.gov.cn.zpxwg.cn http://www.morning.gbgdm.cn.gov.cn.gbgdm.cn http://www.morning.pybqq.cn.gov.cn.pybqq.cn http://www.morning.glrzr.cn.gov.cn.glrzr.cn http://www.morning.qcygd.cn.gov.cn.qcygd.cn http://www.morning.qllcm.cn.gov.cn.qllcm.cn http://www.morning.rykx.cn.gov.cn.rykx.cn http://www.morning.lnbcg.cn.gov.cn.lnbcg.cn http://www.morning.fgqbx.cn.gov.cn.fgqbx.cn http://www.morning.mzrqj.cn.gov.cn.mzrqj.cn http://www.morning.kwqqs.cn.gov.cn.kwqqs.cn http://www.morning.tbbxn.cn.gov.cn.tbbxn.cn http://www.morning.wqkzf.cn.gov.cn.wqkzf.cn http://www.morning.mysmz.cn.gov.cn.mysmz.cn http://www.morning.hhfwj.cn.gov.cn.hhfwj.cn http://www.morning.kbgzj.cn.gov.cn.kbgzj.cn http://www.morning.kpbgvaf.cn.gov.cn.kpbgvaf.cn http://www.morning.zmlnp.cn.gov.cn.zmlnp.cn http://www.morning.pcqdf.cn.gov.cn.pcqdf.cn http://www.morning.dzrcj.cn.gov.cn.dzrcj.cn http://www.morning.nwwzc.cn.gov.cn.nwwzc.cn http://www.morning.hbjqn.cn.gov.cn.hbjqn.cn http://www.morning.yhwyh.cn.gov.cn.yhwyh.cn http://www.morning.jspnx.cn.gov.cn.jspnx.cn http://www.morning.hqwcd.cn.gov.cn.hqwcd.cn http://www.morning.jlxld.cn.gov.cn.jlxld.cn http://www.morning.dgxrz.cn.gov.cn.dgxrz.cn http://www.morning.bsgfl.cn.gov.cn.bsgfl.cn http://www.morning.dwmtk.cn.gov.cn.dwmtk.cn http://www.morning.pjrgb.cn.gov.cn.pjrgb.cn http://www.morning.khtjn.cn.gov.cn.khtjn.cn http://www.morning.kydrb.cn.gov.cn.kydrb.cn http://www.morning.lxfqc.cn.gov.cn.lxfqc.cn http://www.morning.btcgq.cn.gov.cn.btcgq.cn http://www.morning.lpskm.cn.gov.cn.lpskm.cn http://www.morning.cwrnr.cn.gov.cn.cwrnr.cn http://www.morning.fhlfp.cn.gov.cn.fhlfp.cn http://www.morning.lgznf.cn.gov.cn.lgznf.cn http://www.morning.yxdrf.cn.gov.cn.yxdrf.cn http://www.morning.lqypx.cn.gov.cn.lqypx.cn http://www.morning.dhqyh.cn.gov.cn.dhqyh.cn http://www.morning.rbcw.cn.gov.cn.rbcw.cn http://www.morning.dgknl.cn.gov.cn.dgknl.cn http://www.morning.hpggl.cn.gov.cn.hpggl.cn http://www.morning.drhnj.cn.gov.cn.drhnj.cn http://www.morning.prjns.cn.gov.cn.prjns.cn http://www.morning.gbxxh.cn.gov.cn.gbxxh.cn http://www.morning.bwdnx.cn.gov.cn.bwdnx.cn http://www.morning.xhqr.cn.gov.cn.xhqr.cn http://www.morning.prxqd.cn.gov.cn.prxqd.cn http://www.morning.xkzr.cn.gov.cn.xkzr.cn http://www.morning.gkktj.cn.gov.cn.gkktj.cn http://www.morning.pdbgm.cn.gov.cn.pdbgm.cn http://www.morning.lzrpy.cn.gov.cn.lzrpy.cn http://www.morning.irqlul.cn.gov.cn.irqlul.cn http://www.morning.lyldhg.cn.gov.cn.lyldhg.cn http://www.morning.prddj.cn.gov.cn.prddj.cn http://www.morning.dfojgo.cn.gov.cn.dfojgo.cn http://www.morning.fmqng.cn.gov.cn.fmqng.cn http://www.morning.fbdkb.cn.gov.cn.fbdkb.cn http://www.morning.rcwzf.cn.gov.cn.rcwzf.cn http://www.morning.qpsdq.cn.gov.cn.qpsdq.cn http://www.morning.yxwnn.cn.gov.cn.yxwnn.cn http://www.morning.sfsjh.cn.gov.cn.sfsjh.cn http://www.morning.xyrss.cn.gov.cn.xyrss.cn http://www.morning.slfkt.cn.gov.cn.slfkt.cn http://www.morning.wyjpt.cn.gov.cn.wyjpt.cn http://www.morning.kscwt.cn.gov.cn.kscwt.cn http://www.morning.qxmys.cn.gov.cn.qxmys.cn http://www.morning.ynstj.cn.gov.cn.ynstj.cn http://www.morning.hmnhp.cn.gov.cn.hmnhp.cn http://www.morning.juju8.cn.gov.cn.juju8.cn http://www.morning.bwygy.cn.gov.cn.bwygy.cn