使用会话Cookie和JWT身份验证

HTTP是无状态协议,用于传输数据。它启用了客户端和服务器端之间的通信。它最初是为了在Web浏览器和Web服务器之间建立连接而建立的。比如在网上购物,我们添加一些商品,例如。耳机到我们的购物车,然后,我们继续寻找其他项目,在此期间,我们希望在执行任何其他任务是存储购物车项目的状态且不丢失它们。这意味着我们希望在整个购物过程中记住我们的状态。由于HTTP是无状态协议,因此要克服问题,我们可以使用会话或者令牌1、基于会话的身份验证

在JSONWeb令牌出现之前,我们主要使用这种身份验证。在这种身份验证中,服务器负责身份验证,客户端不知道发送请求后服务器端会发生什么。

那么什么是会话Cookie?由于客户端未指定Expires(过期时间)或Max-Age(最大上限)指令,因此在客户端关闭时将其删除。但是,Web浏览器可能会使用会话还原,这会使大多数会话Cookie永久保持状态,就像从未关闭过浏览器一样。

用户在网络浏览器上登录网站发生什么。例如,用户登录后,服务器将为该用户创建一个会话并将该会话数据存储在服务器内存中。当用户在网站上执行某些活动时,会创建一个会话ID,该会话ID存储在客户端浏览器的cookie中。在用户提出的每个请求中,cookie都将随之发送。然后,当用户最初登录时,服务器可以使用存储在服务器内存中的会话数据来验证Cookie上的会话数据。当用户从网站注销时,该会话数据将从数据库和服务器内存中删除。

2、基于令牌的身份验证

在基于令牌的身份验证中,我们使用JWT(JSONWebTokens)进行身份验证。这是RESTfulAPI的广泛使用方法。

当用户发送带有登录详细信息的用户身份验证请求时,服务器将以JSONWEBTOKENS(JWT)的形式创建一个加密的令牌,并将其发送回客户端。当客户端收到令牌时,这意味着该用户以通过身份验证,可以使用客户端执行任何活动。

JWT通常存储在客户端的localstorage中,当用户从服务器请求任何数据或对该网站执行任何活动时,JWT将作为该用户的唯一密钥发送。因此,当服务器接收到该请求时,它将针对每个请求验证JWT仅是该特定用户,然后将所需的响应发送回客户端。

localStorage.setItem("key","value");

用户状态存储在客户端JWT中。当用户注销时,令牌将从客户端(localStorage)中删除。因此,大多数数据存储在客户端,并且可以直接访问,而不是向服务器发送请求。

JSONWEBTOKENS由(.)连接的三个部分组成:1.标头2.有效载荷3.签名

JWT结构:xxxxx.yyyyy.zzzzz

输出包含三个由点分割的Base64-URL字符串,可以在HTML和HTTP环境中轻松传递这些字符串,与基于XML的标准(例如SAML)相比,它更紧凑。

JWT已对先前的标头和有效负载进行了编码,并用一个密钥进行签名,如下

哪个更好用?

在现代Web应用程序中,JWT被广泛使用,因为它的伸缩性优于基于会话的cookie,因为令牌存储在客户端,而会话使用服务器内存来存储用户数据,这可能是一个大问题。大量用户一次访问应用程序。由于JWT是随着每个请求一起发送的,而且包含所有用户信息,因此即使对JWT进行了编码,也有必要在JWT中使用必要的信息,并且应避免使用敏感信息或者将其加密以防止安全攻击。

没有固定的方法可以始终使用,它取决于开发人员和要求的类型,以找出在哪种情况下需要使用哪种方法。

3、jwt实现登录

//定义JWT的有效时长七天privatestaticfinallongEXPIRE_TIME=60**60*24*7;//签发人privatestaticStringISSUER="K_ang";/*秘钥*/privatestaticfinalStringSING="K*^A%$#N

!G";

/***生成令牌**

parammap*

return*/publicstaticStringgetToken(MapString,Stringmap){//设置过期时间Datedate=null;try{date=newDate(System.currentTimeMillis()+EXPIRE_TIME);//创建tokenJWTCreator.Builderbuilder=JWT.create().withIssuer(ISSUER).withExpiresAt(date);//添加信息map.forEach((k,v)-{builder.withClaim(k,v);});returnbuilder.sign(Algorithm.HMAC(SING));}catch(Exceptione){e.printStackTrace();returnnull;}}/***验证token**

paramtoken*/publicstaticbooleanverify(Stringtoken,StringuserNo){try{//设置加密算法JWTVerifierverifier=JWT.require(Algorithm.HMAC(SING)).withClaim("userNo",userNo).build();//校验tokenDecodedJWTjwt=verifier.verify(token);returntrue;}catch(Exceptione){returnfalse;}}/***获取token信息方法**

param*

return*/publicstaticStringgetTokenInfo(Stringtoken){DecodedJWTdecode=JWT.decode(token);returndecode.getClaim("userNo").asString();}}PostMapping("/login")publicResultlogin(

PathParam("empNo")StringempNo,

PathParam("empPassword")StringempPassword){if(empNo==null

"".equals(empNo)){returnResultUtil.error(,"请输入用户名,用户名不能为空");}if(empPassword==null

"".equals(empPassword)){returnResultUtil.error(,"请输入密码,密码不能为空");}Empemp=empService.login(empNo,empPassword);if(emp==null){returnResultUtil.error(,"用户不存在,获取token失败");}if(emp.getEmpPassword()==null

!emp.getEmpPassword().equals(empPassword)){returnResultUtil.error(,"密码错误,获取token失败");}//正常tokenStringtoken=JwtUtils.sign(empNo,empPassword);emp.setToken(token);returnResultUtil.success(,"登录成功",emp);}




转载请注明:http://www.aierlanlan.com/rzdk/5591.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了