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,就可以在后端获取当前登录用户了。

 

posted on 2018-06-26 09:40  动物管理猿  阅读(5038)  评论(2编辑  收藏  举报

导航