springboot 項目 使用 jwt

JSON Web Token (JWT)是一個開放標準(RFC 7519),它定義了一種緊湊的拗小、自包含的方式绊袋,用于作為JSON對象在各方之間安全地傳輸信息。該信息可以被驗證和信任翁潘,因為它是數(shù)字簽名的。

web項目使用jwt的優(yōu)點

1.token 是分布式的由 用戶保存歼争,后端只做校驗
2.jwt可以保存 用戶id 等有效信息拜马。減少查詢數(shù)據(jù)庫操作。
3.有過期時間沐绒,安全俩莽、可靠。

實現(xiàn)方法

這里我們通過spring 的攔截器 + jwt 完成對token的校驗
通過注冊的jwt攔截器洒沦,攔截web請求豹绪,驗證jwt是否有效

1. pom.xml 中添加依賴

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

2. yml 配置文件中 添加如下配置

jwt:
  header: Authorization
  base64Secret:      your-base-64-secret    # your-base-64-secret
  issuer: your-app-server
  expiresSecond: 17280000

3.代碼中添加配置對應(yīng)的 config 文件

/**
 * @author river
 * @create 2018/4/4 下午2:52
 */

@Component
@ConfigurationProperties(prefix = "jwt")
@Data
public class JwtConfig {
    private String base64Secret;
    private String issuer;
    private Long expiresSecond;
    private String header;
}

4. 添加jwt攔截器


/**
 * @author river
 * @create 2018/4/4 上午10:00
 * @desc   用戶的簽名,jwt的解析放在這里
 */
@Slf4j
@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtConfig jwtConfig;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {

        //controller方法調(diào)用之前
        // get jwt token from header - > Authorization
        String jwtToken = httpServletRequest.getHeader(jwtConfig.getHeader());
        //parse jwt , get payload
        Claims claims = JwtUtil.parseJWT(jwtToken,jwtConfig.getBase64Secret());
        log.info("攔截器 -> jwt  jwtToken = {} , claims = {} ",jwtToken, JSONObject.toJSON(claims));

        //用戶未登陸
       // ValidatedUtil.notNull(claims, MsgConstantEnum.NOT_LOGIN);

        Integer userId = (Integer) claims.get("userId");

       // ValidatedUtil.notNull(userId,"用戶id不能為null");
       //ValidatedUtil.notNull(account,"賬號不能為null");

        return true;
    }
}

5. 注冊攔截器


/**
 * @author river
 * @create 2018/4/4 上午9:58
 */
@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter {

    @Resource
    private JwtInterceptor jwtInterceptor;

    /**
     * 添加攔截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor).addPathPatterns("/**") 
                   .excludePathPatterns("/onLogin", "/onRegist");
        super.addInterceptors(registry);
    }
}

提供一個jwt的工具類


@Slf4j
public class JwtUtil {
    
    public static Claims parseJWT(String jsonWebToken, String base64Security){  
        try {  
            Claims claims = Jwts.parser()  
                       .setSigningKey(DatatypeConverter.parseBase64Binary(base64Security))  
                       .parseClaimsJws(jsonWebToken).getBody();  
            return claims;  
        }catch(Exception e) {  
            log.error("驗證token錯誤");
            return null;  
        }
    }  
      
    public static String createJWT(int userId, String account,  String issuer, long TTLMillis, String base64Security) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;  
           
        //生成簽名密鑰  
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Security);  
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
        //添加構(gòu)成JWT的參數(shù)  
        JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT")
                                        .claim("userId", userId)  
                                        .setIssuer(issuer)  
                                        .signWith(signatureAlgorithm, signingKey);  
         //添加Token過期時間 
        if (TTLMillis >= 0) {  
            long nowMillis = System.currentTimeMillis();  
            Date now = new Date(nowMillis);  
            long expMillis = nowMillis + TTLMillis;  
            Date exp = new Date(expMillis);  
            builder.setExpiration(exp).setNotBefore(now);  
        }  
        //生成JWT  
        return builder.compact();  
    }   
}

參考地址
https://jwt.io/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末申眼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蝉衣,更是在濱河造成了極大的恐慌括尸,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件病毡,死亡現(xiàn)場離奇詭異濒翻,居然都是意外死亡,警方通過查閱死者的電腦和手機啦膜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門有送,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人僧家,你說我怎么就攤上這事雀摘。” “怎么了八拱?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵阵赠,是天一觀的道長。 經(jīng)常有香客問我肌稻,道長清蚀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任爹谭,我火速辦了婚禮枷邪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诺凡。我一直安慰自己东揣,他們只是感情好药薯,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著救斑,像睡著了一般童本。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上脸候,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天穷娱,我揣著相機與錄音,去河邊找鬼运沦。 笑死泵额,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的携添。 我是一名探鬼主播嫁盲,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼烈掠!你這毒婦竟也來了羞秤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤左敌,失蹤者是張志新(化名)和其女友劉穎瘾蛋,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矫限,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡哺哼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了叼风。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片取董。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖无宿,靈堂內(nèi)的尸體忽然破棺而出茵汰,到底是詐尸還是另有隱情,我是刑警寧澤懈贺,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布经窖,位于F島的核電站,受9級特大地震影響梭灿,放射性物質(zhì)發(fā)生泄漏画侣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一堡妒、第九天 我趴在偏房一處隱蔽的房頂上張望配乱。 院中可真熱鬧,春花似錦、人聲如沸搬泥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽忿檩。三九已至尉尾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間燥透,已是汗流浹背沙咏。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留班套,地道東北人肢藐。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像吱韭,于是被迫代替她去往敵國和親吆豹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355