>  기사  >  웹 프론트엔드  >  Layui 로그인 후 토큰 문제에 대한 자세한 설명

Layui 로그인 후 토큰 문제에 대한 자세한 설명

尚
앞으로
2019-12-06 17:04:574600검색

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>
#🎜🎜 #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          
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")
                    })
                }
            })

테이블에서 이 코드를 찾으세요. Node.js를 실행하고 위의 구성을 따르세요.

headers: {" token":layui.data(layui.setter.tableName)['token']}, 여기에 요청 헤더를 설정하는 토큰이 있습니다. layui.data(layui.setter.tableName)['로그인 성공 후 테이블에 저장됨.토큰'], 토큰을 운반하는 것은 매우 간단합니다

동시에 업데이트해야 합니다 토큰의 만료 시간이 지났으므로 새 토큰을 가져와서 테이블에 넣어야 합니다

  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의 완전한 방법을 사용하여 토큰을 가져오고 테이블의 이전 토큰을 덮어씁니다. 비어 있으면 덮어쓰지 않습니다.

table 요청을 살펴보겠습니다. jquery는layui에 내장되어 있습니다. 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에 대한 더 많은 지식은
layui 사용법 튜토리얼

컬럼을 주목해주세요.

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

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