springboot-vue-JWT使用

後端引入依賴:html

     <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;
        }
    }
    
}

前端頁面文件:java

     <!-- 登陸 -->
        <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:ios

@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:web

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;
    }

測試登陸:json

登陸成功返回tokenaxios

token本地存儲:後端

存儲在前端app

               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,就能夠在後端獲取當前登陸用戶了。

相關文章
相關標籤/搜索