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元件和工具,幫助開發者快速建立響應式網路應用程式。其特點包括:模組化、輕量級、響應式,並擁有完善的文件和社群支援。 layui廣泛應用於管理後台系統、電商網站和行動裝置應用程式等開發。優點在於上手快、提升效率、維護方便,缺點是客製化較差、技術更新較慢。

layui和vue是前端框架,layui是一種輕量級的函式庫,提供UI元件和工具;vue是一個全面的框架,提供UI元件、狀態管理、資料綁定和路由等功能。 layui基於模組化的架構,vue是基於組件化的架構。 layui擁有較小的生態系統,vue擁有龐大且活躍的生態系統。 layui學習曲線較低,vue學習曲線較陡。 layui適用於小型專案和快速開發UI元件,vue適用於大型專案和需要豐富功能的場景。
