>  기사  >  웹 프론트엔드  >  Layui 로그인 후 토큰 문제가 해결되었습니다.

Layui 로그인 후 토큰 문제가 해결되었습니다.

尚
앞으로
2020-06-05 17:27:184007검색

Layui 로그인 후 토큰 문제가 해결되었습니다.

layui는 매우 간단하고 실용적인 배경 관리 시스템 프레임워크입니다. 플러그인은 풍부하고 사용하기 쉽습니다. 그러나 데이터 처리가 약간 약합니다. 내장된 jquery는 실제 프로세스에서는 약간 부족하지만 내장된 mvc 모드 프레임워크가 추가되면 더 좋을 것 같습니다.

먼저 로그인에서layui 사용을 소개합니다.

로그인 문제는 주로 토큰 저장 호출에 있습니다. 먼저 백그라운드에 토큰 및 인터셉터를 생성하는 코드를 게시합니다.

먼저 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>

토큰. 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;
    }

}

복호화는 주로 parsJWT 방법을 사용합니다

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
          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);

생성된 토큰은 페이지에 있는 정보는 요청 헤더에 배치되며, 백그라운드에서는 인터셉터를 사용하여 만료 여부를 확인합니다. 만료되면 요청이 차단되고 응답 헤더에 새 토큰이 반환됩니다. 만료 시간

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();
            }
        }
    }
}

토큰에 대해 이야기한 후, Layui가 토큰을 저장하는 방법에 대해 이야기하고 렌더링될 때마다 요청 헤더에 토큰을 추가합니다

form.on(&#39;submit(LAY-user-login-submit)&#39;, function (obj) {
            //请求登入接口
            admin.req({
                //实际使用请改成服务端真实接口
                url: &#39;/userInfo/login&#39;,
                method: &#39;POST&#39;,
                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: &#39;15px&#39;,
                            icon: 1,
                            time: 1000
                        }, function () {
                            location.href ="index"

                        });
                    } else {
                        layer.msg(res.msg, {
                            offset: &#39;15px&#39;,
                            icon: 1,
                            time: 1000
                        });
                    }
                }
            });
        });

Layui에 로컬로 저장된 테이블에 반환된 토큰 정보를 저장합니다. 일반적으로layui.setter.tableName을 직접 사용하면 되는데,

layui의 테이블은 js로 렌더링하기 때문에 js에서는 요청 헤더를 설정할 수 없고, 설정하기가 굉장히 번거롭습니다. 그러나 Layui의 데이터 테이블은 Ajax 요청을 기반으로 하므로 Layui 모듈에서 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)[&#39;token&#39;]},
                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(&#39;<div class="&#39; + f + &#39;">&#39; + (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(&#39;<div class="&#39; + f + &#39;">数据接口请求异常:&#39; + 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)[&#39;token&#39;]:xhr.getResponseHeader("token")
                    })
                }
            })

table.js에서 이 코드를 찾으세요. 위의 구성에

headers: {"token":layui.data(layui.setter.tableName)[&#39;token&#39;]},

요청 헤더 설정을 위한 토큰은 다음과 같습니다. 로그인 성공 후 테이블에 저장된layui.data(layui.setter.tableName)['token']으로 이동하면 매우 간단합니다. to carry the token

동시에 토큰의 만료 시간을 업데이트해야 하므로 새로운 토큰을 얻어서 테이블에 넣어야 합니다

 complete: function( xhr,data ){

     layui.data(layui.setter.tableName, {

key: "token",

value: xhr.getResponseHeader("token")==null?layui.data(layui.setter.tableName)[&#39;token&#39;]:xhr.getResponseHeader("token") })

}

토큰을 얻으려면 ajax의 완전한 방법을 사용하세요 비어 있으면 덮어쓰지 않습니다.

테이블이 완성된 후 요청을 살펴보겠습니다. 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)[&#39;token&#39;]},
            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}
        },

또한 인용한 ayui.js 또는layui.all.js에서 ajaxSettings를 찾으세요. 구성하세요

더 많은 layui지식을 보려면 주의하세요. PHP 중국어 웹사이트layui튜토리얼 칼럼

으로

위 내용은 Layui 로그인 후 토큰 문제가 해결되었습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제