zoukankan      html  css  js  c++  java
  • springboot-vue-JWT使用

    后端引入依赖:

         <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>0.7.0</version>
            </dependency>

    JWT工具类:

    package com.tangzhe.util;
    
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.util.Date;
    import io.jsonwebtoken.Claims;
    import io.jsonwebtoken.ExpiredJwtException;
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    import io.jsonwebtoken.SignatureException;
    
    /**
     * API调用认证工具类,采用RSA加密
     */
    public class JWTUtils {
        private static RSAPrivateKey priKey;
        private static RSAPublicKey pubKey;
    
        private static class SingletonHolder {
            private static final JWTUtils INSTANCE = new JWTUtils();
        }
    
        public synchronized static JWTUtils getInstance(String modulus, String privateExponent, String publicExponent) {
            if (priKey == null && pubKey == null) {
                priKey = RSAUtils.getPrivateKey(modulus, privateExponent);
                pubKey = RSAUtils.getPublicKey(modulus, publicExponent);
            }
            return SingletonHolder.INSTANCE;
        }
    
        public synchronized static void reload(String modulus, String privateExponent, String publicExponent) {
            priKey = RSAUtils.getPrivateKey(modulus, privateExponent);
            pubKey = RSAUtils.getPublicKey(modulus, publicExponent);
        }
        
        public synchronized static JWTUtils getInstance() {
            if (priKey == null && pubKey == null) {
                priKey = RSAUtils.getPrivateKey(RSAUtils.modulus, RSAUtils.private_exponent);
                pubKey = RSAUtils.getPublicKey(RSAUtils.modulus, RSAUtils.public_exponent);
            }
            return SingletonHolder.INSTANCE;
        }
        
        /**
         * 获取Token
         * @param uid 用户ID
         * @param exp 失效时间,单位分钟
         * @return
         */
        public static String getToken(String uid, int exp) {
            long endTime = System.currentTimeMillis() + 1000 * exp;
            return Jwts.builder().setSubject(uid).setExpiration(new Date(endTime))
                    .signWith(SignatureAlgorithm.RS512, priKey).compact();
        }
    
        /**
         * 获取Token
         * @param uid 用户ID
         * @return
         */
        public String getToken(String uid) {
            long endTime = System.currentTimeMillis() + 1000 * 60 * 1440;
            return Jwts.builder().setSubject(uid).setExpiration(new Date(endTime))
                    .signWith(SignatureAlgorithm.RS512, priKey).compact();
        }
    
        /**
         * 检查Token是否合法
         * @param token
         * @return JWTResult
         */
        public JWTResult checkToken(String token) {
            try {
                Claims claims = Jwts.parser().setSigningKey(pubKey).parseClaimsJws(token).getBody();
                String sub = claims.get("sub", String.class);
                return new JWTResult(true, sub, "合法请求", ResponseCode.SUCCESS_CODE.getCode());
            } catch (ExpiredJwtException e) {
                // 在解析JWT字符串时,如果‘过期时间字段’已经早于当前时间,将会抛出ExpiredJwtException异常,说明本次请求已经失效
                return new JWTResult(false, null, "token已过期", ResponseCode.TOKEN_TIMEOUT_CODE.getCode());
            } catch (SignatureException e) {
                // 在解析JWT字符串时,如果密钥不正确,将会解析失败,抛出SignatureException异常,说明该JWT字符串是伪造的
                return new JWTResult(false, null, "非法请求", ResponseCode.NO_AUTH_CODE.getCode());
            } catch (Exception e) {
                return new JWTResult(false, null, "非法请求", ResponseCode.NO_AUTH_CODE.getCode());
            }
        }
    
        public static class JWTResult {
            private boolean status;
            private String uid;
            private String msg;
            private int code;
            
            public JWTResult() {
                super();
            }
    
            public JWTResult(boolean status, String uid, String msg, int code) {
                super();
                this.status = status;
                this.uid = uid;
                this.msg = msg;
                this.code = code;
            }
            
            public int getCode() {
                return code;
            }
    
            public void setCode(int code) {
                this.code = code;
            }
    
            public String getMsg() {
                return msg;
            }
    
            public void setMsg(String msg) {
                this.msg = msg;
            }
    
            public boolean isStatus() {
                return status;
            }
    
            public void setStatus(boolean status) {
                this.status = status;
            }
    
            public String getUid() {
                return uid;
            }
    
            public void setUid(String uid) {
                this.uid = uid;
            }
        }
        
    }

    前端页面文件:

         <!-- 登录 -->
            <div>
                <p>用户名:<input v-model="username" /></p>
                <p>密码:<input v-model="password" /></p>
                <button @click="login">登录</button>
            </div>
    ...        
    login: function() {
    axios.post('http://localhost:8889/user/login', {
    username: this.username,
    password: this.password,
    })
    .then(function (response) {
    if (response.data.status) {
    alert(response.data.token);
    } else {
    alert("登录失败");
    }
    })
    .catch(function (error) {
    console.log(error);
    });
    }
    
    

    后端controller:

    @PostMapping("/login")
        public Object login(@RequestBody LoginInfo loginInfo) {
            Map<String, Object> result = new HashMap<>();
            String token = userService.login(loginInfo);
            if (token == null) {
                result.put("status", false);
            } else {
                result.put("status", true);
                result.put("token", token);
            }
            return result;
        }

    后端service:

    public String login(LoginInfo loginInfo) {
            User user = userRepository.findByUsernameAndPassword(loginInfo.getUsername(), loginInfo.getPassword());
            if (user == null) {
                return null;
            }
            String token = JWTUtils.getInstance().getToken(user.getId() + "");
            return token;
        }

    测试登录:

    登录成功返回token

    token本地存储:

    存储在前端

                   login: function() {
                        axios.post('http://localhost:8889/user/login', {
                            username: this.username,
                            password: this.password,
                        })
                            .then(function (response) {
                                if (response.data.status) {
                                    alert(response.data.token);
                                    // token本地存储
                                    localStorage.setItem("token", response.data.token);
                                } else {
                                    alert("登录失败");
                                }
                            })
                            .catch(function (error) {
                                console.log(error);
                            });
                    }
    // 从html本地存储中拿出token,设置到全局请求头中
    axios.defaults.headers.common['Authorization'] = localStorage.getItem("token");
    这样每次发送请求就能带上token的请求头了


    后端解析请求头获取token,并借助jwt工具类解密出当前登录用户id:
    public class LoginInfoUtils {
    
        /**
         * 获取当前登录用户id
         */
        public static String getLoginUserId(HttpServletRequest request) {
            String authorization = request.getHeader("Authorization");
            if (StringUtils.isNotBlank(authorization)) {
                JWTUtils.JWTResult result = JWTUtils.getInstance().checkToken(authorization);
                if (result.isStatus()) {
                    return result.getUid();
                }
            }
            return null;
        }
    
    }

    后端控制台输出当前登录用户ID:

    @GetMapping("/list")
        public List<User> list(HttpServletRequest request) {
            // 获取当前登录用户id
            System.out.println("当前用户ID: " + LoginInfoUtils.getLoginUserId(request));
            return userService.findAll();
        }

    若还没登录则输出:当前用户ID: null

    用户登录则输出:当前用户ID: 6

    这样,前端发送请求时,请求头中带有后端登录接口返回的token值,

    后端可以从请求头中获取token并通过JWT解密获得当前登录用户id,就可以在后端获取当前登录用户了。

  • 相关阅读:
    Android实现不同Active页面间的跳转
    Android Dialog的整个生命周期
    fragment的基本用法
    使用URLEncoder、URLDecoder进行URL参数的转码与解码
    Android 通过URL获取网络资源
    Dialog向Activity传递数据
    Android 自定义AlertDialog(退出提示框)
    javascript的继承实现
    UVA Graph Coloring
    poj3744高速功率矩阵+可能性DP
  • 原文地址:https://www.cnblogs.com/tangzhe/p/9227564.html
Copyright © 2011-2022 走看看