SpringBoot最簡單的實現JWT

2020-10-26 14:00:38

什麼是JWT

Json web token (JWT), 是為了在網路應用環境間傳遞宣告而執行的一種基於JSON的開放標準((RFC 7519).定義了一種簡潔的,自包含的方法用於通訊雙方之間以JSON物件的形式安全的傳遞資訊。因為數位簽章的存在,這些資訊是可信的,JWT可以使用HMAC演演算法或者是RSA的公私祕鑰對進行簽名。

JWT官網: https://jwt.io

JWT的主要應用場景

身份認證在這種場景下,一旦使用者完成了登陸,在接下來的每個請求中包含JWT,可以用來驗證使用者身份以及對路由,服務和資源的存取許可權進行驗證。由於它的開銷非常小,可以輕鬆的在不同域名的系統中傳遞,所有目前在單點登入(SSO)中比較廣泛的使用了該技術。 資訊交換在通訊的雙方之間使用JWT對資料進行編碼是一種非常安全的方式,由於它的資訊是經過簽名的,可以確保傳送者傳送的資訊是沒有經過偽造的。

JWT的結構

JWT包含了三部分:

Header 頭部(標題包含了令牌的後設資料,並且包含簽名和/或加密演演算法的型別)
Payload 負載 (類似於飛機上承載的物品)
Signature 簽名/簽證

將這三段資訊文字用.連線一起就構成了JWT字串。

就像這樣:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

下來我們通過springboot來實現jwt令牌的生成

新增pom依賴 待會需要用到json所以一起引入進來

 <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.51</version>
        </dependency>
    <dependency>

新增controller和service以及實體類,為了方便就沒運算元據庫我們採用固定的使用者名稱和密碼,整體的結果如下

在這裡插入圖片描述

controller

@RequestMapping("/user")
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping(value = "/login")
    public String login(@RequestBody User user){
        return userService.login(user);
    }
}

實現類

public class UserServiceImpl implements UserService {
    public static final String USERNAME = "admin";
    public static final String PASSWORD = "admin";

    @Override
    public String login(User user) {
        //忽略查詢資料庫
        if (USERNAME.equals(user.getName()) && PASSWORD.equals(user.getPassword())){
            //建立使用者令牌資訊
            Map<String, Object> map = new HashMap<>();
            map.put("role","USER");
            map.put("success","SUCCESS");
            map.put("username",user.getName());
            //建立使用者Token
            String token = JwtUtil.createJWT(UUID.randomUUID().toString(), JSON.toJSONString(map), null);
            //現在就可以儲存tonken了,為了方便直接存到cookie裡面去
            Cookie cookie = new Cookie("Authoriztion", token);
            cookie.setDomain("localhost");
            cookie.setPath("/");
            return token;
        }
        return "登入失敗";
    }

    @Override
    public List<User> getUserInfo() {
        return null;
    }

}

其中JwtUtil類為主要程式碼 程式碼如下,該類裡面封裝了生成token的資訊

public class JwtUtil {
    //令牌有效期 1小時
    public static final Long JWT_TTL = 3600000L;

    //jwt令牌資訊
    public static final String JWT_KEY = "mzjmc";


    public static String createJWT(String id, String subject, Long ttlMillis){
        //指定簽名演演算法
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        //當前系統時間
        long currentTimeMillis = System.currentTimeMillis();
        //令牌簽發的時間
        Date date = new Date(currentTimeMillis);
        //如果令牌的有效期為空則預設一小時
        if (ttlMillis == null){
            ttlMillis = JWT_TTL;
        }
        //令牌過期時間
        long expMillis = currentTimeMillis + ttlMillis;
        Date expDate = new Date(expMillis);
        //生成祕鑰
        SecretKey secretKey = generalKey();
        //封裝jwt資訊
        JwtBuilder jwtBuilder = Jwts.builder();
        jwtBuilder.setId(id); //唯一ID
        jwtBuilder.setSubject(subject); //主題資訊
        jwtBuilder.setIssuer("admin");  //簽發者
        jwtBuilder.setIssuedAt(date); //簽發時間
        jwtBuilder.signWith(SignatureAlgorithm.HS256, secretKey); //演演算法及簽名祕鑰
        jwtBuilder.setExpiration(expDate);  //過期時間

        return jwtBuilder.compact();
    }

    /**
     * 生成祕鑰
     * @return
     */
    public static SecretKey generalKey(){
        byte[] encode = Base64.getEncoder().encode(JWT_KEY.getBytes());
        return new SecretKeySpec(encode, 0, encode.length, "AES");
    }
}

接下來我們可以測試通過登入獲取token資訊。指定了使用者名稱和密碼為admin

先來一組錯的

在這裡插入圖片描述

再來一組對的

在這裡插入圖片描述

是不是很簡單,2020-1024今天自己過節還是很Happy的

在這裡插入圖片描述
在這裡插入圖片描述