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,就可以在后端獲取當前登錄用戶了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM