• JWT实现用户权限认证


    网上的java基础教程曾教会我们,将用户登录信息存在session(服务器端)中,需要验证的时候拿出来作对比以达到身份

    验证的效果。但这种方式暴露的问题也是可想而知的:

    1.Seesion:每次认证用户发起请求时,服务器需要去创建一个记录来存储信息。当越来越多的用户发请求时,内存的开销也会不断增加。

    2.可扩展性:在服务端的内存中使用Seesion存储登录信息,伴随而来的是可扩展性问题。

    3.CORS(跨域资源共享):当我们需要让数据跨多台移动设备上使用时,跨域资源的共享会是一个让人头疼的问题。在使用Ajax抓取另一个

    域的资源,就可以会出现禁止请求的情况。

    4.CSRF(跨站请求伪造):用户在访问网站时,他们很容易受到跨站请求伪造的攻击,并且能够被利用其访问其他的网站。

    在这些问题中,可扩展行是最突出的。因此我们有必要去寻求一种更有行之有效的方法。

    而token却能解决在服务端存储信息时的许多问题:

    1.用户登录

    和往常一样,一个表单,输入用户名、密码然后登录

        <form action="servlet/Addcookies" method="post">
            <label>账    号:</label><input type="text" name="username" /><br> 
            <label>密    码:</label><input  type="password" name="password" /><br>
            <button type="submit">登录</button>
        </form>

    可以看到,这个表单提交到一个servlet

    2.servlet

    下面看这个servlet

        public void doGet(HttpServletRequest request, HttpServletResponse response)
                throws IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
            String username = request.getParameter("username");
            String Token = null;
            try {
                Token = JwtToken.creatToken(username);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Cookie cookie = new Cookie("token", Token);
            cookie.setPath("/"); // 设置路径使得cookie共享
            cookie.setMaxAge(1000);// 设置cookie有效期
            response.addCookie(cookie);// 向客户端添加cookie
            response.sendRedirect("../index2.jsp");// 请求转发
        }

    根据表单发来的请求,获取username参数值;

    根据username参数值生成Token(具体方法后面讲);

    新建一个cookie,key值为token,value值为之前生成的Token;

    页面跳转到index2.jsp。

    3.index2.jsp

    页面没什么,直接看js

    //定义一个function,根据name获取该cookie的value值
    function getCookie(name){
        //获取cookies并分割成数组形式
        var strcookie = document.cookie;
        var arrcookie = strcookie.split("; ");
        //遍历所有cookie,并根据参数返回对应cookie的vaule
        for ( var i = 0; i < arrcookie.length; i++) {
            var arr = arrcookie[i].split("=");
            if (arr[0] == name){
                return encodeURIComponent(arr[1]);
            }
        }
        return "找不到指定cookie或cookie过期了";
    }
    
    
    var token=getCookie("token");
    document.getElementById("go").innerHTML=token;

    这样,就将存在cookie里面的token拿到了,之后需要验证用户权限的话,就将这个token作为参数放到请求中;

    服务端接收到这个携带token的请求,会对token解析,如果解析成功,就表示权限认证通过。

    4.Token的生成与解析

    直接看这个工具类

    package com.eco.util;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import com.auth0.jwt.JWT;
    import com.auth0.jwt.JWTVerifier;
    import com.auth0.jwt.algorithms.Algorithm;
    import com.auth0.jwt.interfaces.Claim;
    import com.auth0.jwt.interfaces.DecodedJWT;
    
    public class JwtToken {
        /* 生成token加密所需的公钥,位于服务端 */
        public static String SECRET = "eco";
    
        /*
         * 根据用户登录信息(用户名、密码)生成token
         * 
         * @pram name 用户请求提供的某个参数
         */
    
        public static String creatToken(String name) throws Exception {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("alg", "HS256");
            map.put("typ", "JWT");
            String token = JWT.create().withHeader(map).withClaim("name", name)
                    .sign(Algorithm.HMAC384(SECRET));
            return token;
        }
    
        /*
         * 解析用户请求提供的token字符串,返回map
         * 
         * @pram token 用户请求提供的token
         */
    
        public static Map<String, Claim> verifyToken(String token) throws Exception {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC384(SECRET)).build();
            DecodedJWT jwt = null;
            jwt = verifier.verify(token);
            return jwt.getClaims();
        }
    }
  • 相关阅读:
    Salt-ssh批量自动安装被控端salt-mini
    Saltstack配置管理
    gitlab的安装和基本维护
    Git的杀手级功能之 一 远程仓库
    分布式版本控制系统-git
    Linux查看服务器公网ip的方法
    vmware fusion 10序列号
    python3.6.4的importlib模块重载用法
    设置PyCharm中的Python代码模版
    MacOs执行SQL出错(mysql)
  • 原文地址:https://www.cnblogs.com/eco-just/p/8633310.html
Copyright © 2020-2023  润新知