• 使用JWT实现Token认证


    为什么使用JWT?
    随着技术的发展,分布式web应用的普及,通过session管理用户登录状态成本越来越高,因此慢慢发展成为token的方式做登录身份校验,然后通过token去取redis中的缓存的用户信息,随着之后jwt的出现,校验方式更加简单便捷化,无需通过redis缓存,而是直接根据token取出保存的用户信息,以及对token可用性校验,单点登录更为简单。

    JWT架构图


    JWT架构图.png

    使用JWT核心代码:
    maven依赖:

            <dependency>
                <groupId>com.auth0</groupId>
                <artifactId>java-jwt</artifactId>
                <version>3.2.0</version>
            </dependency>
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.7.0</version>
            </dependency>
    

    JWT工具类:
    用于生成Token,和Token验证

    public class JwtUtils {
        /**
         * 签发JWT
         * @param id
         * @param subject 可以是JSON数据 尽可能少
         * @param ttlMillis
         * @return  String
         *
         */
        public static String createJWT(String id, String subject, long ttlMillis) {
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
            long nowMillis = System.currentTimeMillis();
            Date now = new Date(nowMillis);
            SecretKey secretKey = generalKey();
            JwtBuilder builder = Jwts.builder()
                    .setId(id)
                    .setSubject(subject)   // 主题
                    .setIssuer("user")     // 签发者
                    .setIssuedAt(now)      // 签发时间
                    .signWith(signatureAlgorithm, secretKey); // 签名算法以及密匙
            if (ttlMillis >= 0) {
                long expMillis = nowMillis + ttlMillis;
                Date expDate = new Date(expMillis);
                builder.setExpiration(expDate); // 过期时间
            }
            return builder.compact();
        }
        /**
         * 验证JWT
         * @param jwtStr
         * @return
         */
        public static CheckResult validateJWT(String jwtStr) {
            CheckResult checkResult = new CheckResult();
            Claims claims = null;
            try {
                claims = parseJWT(jwtStr);
                checkResult.setSuccess(true);
                checkResult.setClaims(claims);
            } catch (ExpiredJwtException e) {
                checkResult.setErrCode(SystemConstant.JWT_ERRCODE_EXPIRE);
                checkResult.setSuccess(false);
            } catch (SignatureException e) {
                checkResult.setErrCode(SystemConstant.JWT_ERRCODE_FAIL);
                checkResult.setSuccess(false);
            } catch (Exception e) {
                checkResult.setErrCode(SystemConstant.JWT_ERRCODE_FAIL);
                checkResult.setSuccess(false);
            }
            return checkResult;
        }
        public static SecretKey generalKey() {
            byte[] encodedKey = Base64.decode(SystemConstant.JWT_SECERT);
            SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
            return key;
        }
    
    <span class="hljs-comment">/**
     * 
     * 解析JWT字符串
     * <span class="hljs-doctag">@param</span> jwt
     * <span class="hljs-doctag">@return</span>
     * <span class="hljs-doctag">@throws</span> Exception
     */</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Claims <span class="hljs-title">parseJWT</span><span class="hljs-params">(String jwt)</span> <span class="hljs-keyword">throws</span> Exception </span>{
        SecretKey secretKey = generalKey();
        <span class="hljs-keyword">return</span> Jwts.parser()
            .setSigningKey(secretKey)
            .parseClaimsJws(jwt)
            .getBody();
    }
    

    }

    如何使用?
    代码实例:

    public class LoginController {
        @Autowired
        UserRepository userRepository;
    
    <span class="hljs-meta">@ApiOperation</span>(value=<span class="hljs-string">"用户登陆"</span>)
    <span class="hljs-meta">@RequestMapping</span>(value=<span class="hljs-string">"login"</span>,method = RequestMethod.POST)
    <span class="hljs-function"><span class="hljs-keyword">public</span> ReturnVo <span class="hljs-title">login</span><span class="hljs-params">(String username, String password,HttpServletResponse
            response)</span> </span>{
        User user =  userRepository.findByUsername(username);
        <span class="hljs-keyword">if</span>(user!=<span class="hljs-keyword">null</span>){
            <span class="hljs-keyword">if</span>(user.getPassword().equals(password)){
                <span class="hljs-comment">//把token返回给客户端--&gt;客户端保存至cookie--&gt;客户端每次请求附带cookie参数</span>
                String JWT = JwtUtils.createJWT(<span class="hljs-string">"1"</span>, username, SystemConstant.JWT_TTL);
                <span class="hljs-keyword">return</span> ReturnVo.ok(JWT);
            }<span class="hljs-keyword">else</span>{
                <span class="hljs-keyword">return</span> ReturnVo.error();
            }
        }<span class="hljs-keyword">else</span>{
            <span class="hljs-keyword">return</span> ReturnVo.error();
        }
    }
    <span class="hljs-meta">@ApiOperation</span>(value=<span class="hljs-string">"获取用户信息"</span>)
    <span class="hljs-meta">@RequestMapping</span>(value=<span class="hljs-string">"description"</span>,method = RequestMethod.POST)
    <span class="hljs-function"><span class="hljs-keyword">public</span> ReturnVo <span class="hljs-title">description</span><span class="hljs-params">(String username)</span> </span>{
        User user =  userRepository.findByUsername(username);
        <span class="hljs-keyword">return</span> ReturnVo.ok(user.getDescription());
    }
    

    }

          </div>
  • 相关阅读:
    Perl 基础笔记: 使用 cpanm 安装 Perl 模块
    修改CPAN安装源
    JQUERY实现点击INPUT使光标移动到最后或指定位置
    新手入门Underscore.js 中文(template)
    深入浅出C/C++中的正则表达式库
    [libxml2]_[XML处理]_[使用libxml2的xpath特性修改xml文件内容]
    Mysql事务的隔离级别
    HBase基础知识摘要
    java如何实现一个Future
    遇到过的问题整理-大量页面监控问题
  • 原文地址:https://www.cnblogs.com/jpfss/p/10929458.html
Copyright © 2020-2023  润新知