layui登录后token问题解决
layui是一个非常简单且实用的后台管理系统搭建框架,里面的插件丰富使用简单,只需要在原有基础上进行修改即可,但是在数据处理方面略显薄弱,内置的jquery在实际过程中略显不足,若是能添加内置的mvc模式框架那就更好了。
先介绍layui在登录这一块的使用:
登录问题主要是在token的存储调用上,先贴出后台的创建token以及拦截器的代码
首先引入jar包
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.7.0</version> <exclusions> <exclusion> <artifactId>jackson-databind</artifactId> <groupId>com.fasterxml.jackson.core</groupId> </exclusion> </exclusions> </dependency>
token使用io.jsonwebtoken ,可以自定义秘钥,并存储登录信息
package com.zeus.utils; import cn.hutool.json.JSON; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.zeus.constant.CommonConstants; import io.jsonwebtoken.Claims; import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import java.security.Key; import java.util.Date; public class TokenUtil { private static Logger LOG = LoggerFactory.getLogger(TokenUtil.class); /** * 创建TOKEN * * @param id, issuer, subject, ttlMillis * @return java.lang.String * @methodName createJWT * @author fusheng * @date 2019/1/10 */ public static String createJWT(String id, String issuer, String subject, long ttlMillis) { SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis); byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("englishlearningwebsite"); Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName()); JwtBuilder builder = Jwts.builder().setId(id) .setIssuedAt(now) .setSubject(subject) .setIssuer(issuer) .signWith(signatureAlgorithm, signingKey); if (ttlMillis >= 0) { long expMillis = nowMillis + ttlMillis; Date exp = new Date(expMillis); builder.setExpiration(exp); } return builder.compact(); } /** * 解密TOKEN * * @param jwt * @return io.jsonwebtoken.Claims * @methodName parseJWT * @author fusheng * @date 2019/1/10 */ public static Claims parseJWT(String jwt) { Claims claims = Jwts.parser() .setSigningKey(DatatypeConverter.parseBase64Binary("englishlearningwebsite")) .parseClaimsJws(jwt).getBody(); return claims; } }
解密主要使用到 parseJWT 方法
public static Contact getContact(String token) { Claims claims = null; Contact contact = null; if (token != null) { //得到claims类 claims = TokenUtil.parseJWT(token); cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(claims.getSubject()); contact = jsonObject.get("user", Contact.class); } return contact; }
claims 中是解密后的token类,存储token中的全部信息
//解密token claims = TokenUtil.parseJWT(token); //得到用户的类型 String issuer = claims.getIssuer(); //得到登录的时间 Date issuedAt = claims.getIssuedAt(); //得到设置的登录id String id = claims.getId(); //claims.getExpiration().getTime() > DateUtil.date().getTime() ,判断tokern是否过期 //得到存入token的对象 cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(claims.getSubject()); Contact contact = jsonObject.get("user", Contact.class);
创建好的token会在页面中放置到请求头中,后台通过来拦截器来判断是否过期,若过期则拦截请求,成功则在响应头中返回新的token更新过期时间
package com.zeus.interceptor; import cn.hutool.core.date.DateUtil; import cn.hutool.json.JSON; import cn.hutool.json.JSONUtil; import com.zeus.utils.TokenUtil; import io.jsonwebtoken.Claims; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; import java.util.Map; import static com.zeus.constant.CommonConstants.EFFECTIVE_TIME; /** * 登陆拦截器 * * @author:fusheng * @date:2019/1/10 * @ver:1.0 **/ public class LoginHandlerIntercepter implements HandlerInterceptor { private static final Logger LOG = LoggerFactory.getLogger(LoginHandlerIntercepter.class); /** * token 校验 * * @param httpServletRequest, httpServletResponse, o * @return boolean * @methodName preHandle * @author fusheng * @date 2019/1/3 0003 */ @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { Map<String, String[]> mapIn = httpServletRequest.getParameterMap(); JSON jsonObject = JSONUtil.parseObj(mapIn); StringBuffer stringBuffer = httpServletRequest.getRequestURL(); LOG.info("httpServletRequest ,路径:" + stringBuffer + ",入参:" + JSONUtil.toJsonStr(jsonObject)); //校验APP的登陆状态,如果token 没有过期 LOG.info("come in preHandle"); String oldToken = httpServletRequest.getHeader("token"); LOG.info("token:" + oldToken); /*刷新token,有效期延长至一个月*/ if (StringUtils.isNotBlank(oldToken)) { Claims claims = null; try { claims = TokenUtil.parseJWT(oldToken); } catch (Exception e) { e.printStackTrace(); String str = "{\"code\":801,\"msg\":\"登陆失效,请重新登录\"}"; dealErrorReturn(httpServletRequest, httpServletResponse, str); return false; } if (claims.getExpiration().getTime() > DateUtil.date().getTime()) { String userId = claims.getId(); try { String newToken = TokenUtil.createJWT(claims.getId(), claims.getIssuer(), claims.getSubject(), EFFECTIVE_TIME); LOG.info("new TOKEN:{}", newToken); httpServletRequest.setAttribute("userId", userId); httpServletResponse.setHeader("token", newToken); LOG.info("flush token success ,{}", oldToken); return true; } catch (Exception e) { e.printStackTrace(); String str = "{\"code\":801,\"msg\":\"登陆失效,请重新登录\"}"; dealErrorReturn(httpServletRequest, httpServletResponse, str); return false; } } } String str = "{\"code\":801,\"msg\":\"登陆失效,请重新登录\"}"; dealErrorReturn(httpServletRequest, httpServletResponse, str); return false; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } /** * 返回错误信息给WEB * * @param httpServletRequest, httpServletResponse, obj * @return void * @methodName dealErrorReturn * @author fusheng * @date 2019/1/3 0003 */ public void dealErrorReturn(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object obj) { String json = (String) obj; PrintWriter writer = null; httpServletResponse.setCharacterEncoding("UTF-8"); httpServletResponse.setContentType("application/json; charset=utf-8"); try { writer = httpServletResponse.getWriter(); writer.print(json); } catch (IOException ex) { LOG.error("response error", ex); } finally { if (writer != null) { writer.close(); } } } }
讲完了token ,再讲layui如何存储token,并在每次渲染时添加token到请求头中
form.on('submit(LAY-user-login-submit)', function (obj) { //请求登入接口 admin.req({ //实际使用请改成服务端真实接口 url: '/userInfo/login', method: 'POST', data: obj.field, done: function (res) { if (res.code === 0) { //请求成功后,写入 access_token layui.data(setter.tableName, { key: "token", value: res.data.token }); //登入成功的提示与跳转 layer.msg(res.msg, { offset: '15px', icon: 1, time: 1000 }, function () { location.href ="index" }); } else { layer.msg(res.msg, { offset: '15px', icon: 1, time: 1000 }); } } }); });
我们将返回的token信息存入layui本地存储的表中,在config.js中会配置表名,一般直接使用layui.setter.tableName 即可,
由于layui的table 是通过js渲染的,我们无法在js中对它进行设置请求头,而且每一个表格都要配置极为麻烦,但layui的数据表格是基于ajax请求的,所以我们选在在layui的module中手动修改table.js使得,每次请求是都会自动携带请求头
a.contentType && 0 == a.contentType.indexOf("application/json") && (d = JSON.stringify(d)), t.ajax({ type: a.method || "get", url: a.url, contentType: a.contentType, data: d, dataType: "json", headers: {"token":layui.data(layui.setter.tableName)['token']}, success: function (t) { if(t.code==801){ top.location.href = "index"; }else { "function" == typeof a.parseData && (t = a.parseData(t) || t), t[n.statusName] != n.statusCode ? (i.renderForm(), i.layMain.html('<div class="' + f + '">' + (t[n.msgName] || "返回的数据不符合规范,正确的成功状态码 (" + n.statusName + ") 应为:" + n.statusCode) + "</div>")) : (i.renderData(t, e, t[n.countName]), o(), a.time = (new Date).getTime() - i.startTime + " ms"), i.setColsWidth(), "function" == typeof a.done && a.done(t, e, t[n.countName]) } }, error: function (e, t) { i.layMain.html('<div class="' + f + '">数据接口请求异常:' + t + "</div>"), i.renderForm(), i.setColsWidth() }, complete: function( xhr,data ){ layui.data(layui.setter.tableName, { key: "token", value: xhr.getResponseHeader("token")==null?layui.data(layui.setter.tableName)['token']:xhr.getResponseHeader("token") }) } })
在table.js中找到这一代码,按上面的配置
headers: {"token":layui.data(layui.setter.tableName)['token']},
这里是设置请求头的token,拿到登录成功后存储在表中的layui.data(layui.setter.tableName)['token'], 这样既可携带token很简单
同时我们需要更新token的过期时间,那么就要拿到新的token,并放入表中
complete: function( xhr,data ){ layui.data(layui.setter.tableName, { key: "token", value: xhr.getResponseHeader("token")==null?layui.data(layui.setter.tableName)['token']:xhr.getResponseHeader("token") }) }
使用ajax的complete方法拿到token,并覆盖表的旧token,如果为空则不覆盖
table讲完,来看看请求,layui中内置了jquery,可以使用var $ = layui,jquery, 来使用内置的ajax,那么我们也需要对ajax进行配置
pe.extend({ active: 0, lastModified: {}, etag: {}, ajaxSettings: { url: en, type: "GET", isLocal: Vt.test(tn[1]), global: !0, processData: !0, async: !0, headers: {"token":layui.data(layui.setter.tableName)['token']}, contentType: "application/x-www-form-urlencoded; charset=UTF-8", accepts: { "*": Zt, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: {xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/}, responseFields: {xml: "responseXML", text: "responseText", json: "responseJSON"}, converters: {"* text": String, "text html": !0, "text json": pe.parseJSON, "text xml": pe.parseXML}, flatOptions: {url: !0, context: !0} },
同样在l你引用的ayui.js或者layui.all.js中找到 ajaxSettings:配置一下即可
以上是layui登录后token问题解决的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

layui 登录页面跳转设置步骤:添加跳转代码:在登录表单提交按钮点击事件中添加判断,成功登录后通过 window.location.href 跳转到指定页面。修改 form 配置:在 lay-filter="login" 的 form 元素中添加 hidden 输入字段,name 为 "redirect",value 为目标页面地址。

layui 提供了多种获取表单数据的方法,包括直接获取表单所有字段数据、获取单个表单元素值、使用 formAPI.getVal() 方法获取指定字段值、将表单数据序列化并作为 AJAX 请求参数,以及监听表单提交事件获取数据。

layui与Vue的区别主要体现在功能和关注点上。layui专注于快速开发UI元素,提供预制组件简化页面构建;而Vue是一个全栈框架,注重数据绑定、组件化开发和状态管理,更适合构建复杂应用程序。 layui学习简单,适合快速构建页面;Vue学习曲线陡峭,但有助于构建可扩展和易维护的应用程序。根据项目需求和开发者技能水平,可以选择合适的框架。

通过使用layui框架的响应式布局功能,可以实现自适应布局。步骤包括:引用layui框架。定义自适应布局容器,设置layui-container类。使用响应式断点(xs/sm/md/lg)隐藏特定断点下的元素。利用网格系统(layui-col-)指定元素宽度。通过偏移量(layui-offset-)创建间距。使用响应式实用工具(layui-invisible/show/block/inline)控制元素的可见性和显示方式。

使用 layui 传输数据的方法如下:使用 Ajax:创建请求对象,设置请求参数(URL、方法、数据),处理响应。使用内置方法:使用 $.post、$.get、$.postJSON 或 $.getJSON 等内置方法简化数据传输。

layui是一个前端UI框架,它提供了丰富的UI组件、工具和功能,帮助开发人员快速构建现代化、响应式和交互式Web应用程序,特点包括:灵活轻量、模块化设计、丰富的组件、强大的工具和易于定制。它广泛应用于各种Web应用程序的开发中,包括管理系统、电商平台、内容管理系统、社交网络和移动端应用。

layui框架是一款基于JavaScript的前端框架,提供了一套易用的UI组件和工具,帮助开发者快速构建响应式Web应用。其特点包括:模块化、轻量级、响应式,并拥有完善的文档和社区支持。layui广泛应用于管理后台系统、电商网站和移动端应用等开发中。优点在于上手快、提高效率、维护方便,缺点是定制性较差、技术更新较慢。

layui和vue是前端框架,layui是一种轻量级的库,提供UI组件和工具;vue是一个全面的框架,提供UI组件、状态管理、数据绑定和路由等功能。layui基于模块化的架构,vue基于组件化的架构。layui拥有较小的生态系统,vue拥有庞大且活跃的生态系统。layui学习曲线较低,vue学习曲线较陡。layui适用于小型项目和快速开发UI组件,vue适用于大型项目和需要丰富功能的场景。
