1. 程式人生 > >Spring Boot 使用 Jwt + Swagger2 搭建帶身份驗證的介面服務

Spring Boot 使用 Jwt + Swagger2 搭建帶身份驗證的介面服務

首先需要搭建好一個Spring Boot + Swagger2的專案
因為之前有寫過 Swagger2 點我 所以這裡就不再重複一遍了。該文章將會在之前專案的基礎上繼續新增整合Jwt。

首先放下搭建完畢的專案目錄結構

這裡寫圖片描述

pom.xml
在之前的基礎上新增Jwt依賴即可

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

新增JwtAuthenticationFilter.java檔案
如名字,這是一個攔截器,當用戶訪問介面時將會被該攔截器攔截,我們可以通過修改isProtectedUrl函式中的範圍來確定需要攔截的範圍。
然後因為Jwt預設是用儲存在header中的驗證碼來驗證身份的,這對於Swagger2來說很難進行測試,需要對Swagger2進行修改,比較麻煩,所以這裡我直接修改成了從Body中取,當然同理也可以替換成cookie,session中,都行。

package com.my.swagger2.filter;

import org.springframework.util.AntPathMatcher;
import
org.springframework.util.PathMatcher; import org.springframework.web.filter.OncePerRequestFilter; import com.my.swagger2.util.JwtUtil; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import
java.io.IOException; public class JwtAuthenticationFilter extends OncePerRequestFilter { private static final PathMatcher pathMatcher = new AntPathMatcher(); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { //解決跨域問題 response.setHeader("Access-Control-Allow-Origin", "*"); try { if(isProtectedUrl(request)) { //因為jwt用來驗證身份的驗證碼是儲存在header中的,而用swagger2時header中的值不好設定,需要進行修改,因此這裡改成了從body中獲取 //String token = request.getHeader("Authorization"); String token = request.getParameter("Authorization"); //檢查jwt令牌, 如果令牌不合法或者過期, 裡面會直接丟擲異常, 下面的catch部分會直接返回 JwtUtil.validateToken(token); } } catch (Exception e) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage()); return; } //如果jwt令牌通過了檢測, 那麼就把request傳遞給後面的RESTful api filterChain.doFilter(request, response); } //我們只對地址 /api 開頭的api檢查jwt. 不然的話登入/login也需要jwt private boolean isProtectedUrl(HttpServletRequest request) { return pathMatcher.match("/api/**", request.getServletPath()); } }

新增Jwt配置檔案
JwtUtil.java
這裡定義了Jwt驗證碼的格式,用到的引數等等,還有有效時間,為了測試方便,這裡定的是1000小時。

package com.my.swagger2.util;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtUtil {
    static final String SECRET = "ThisIsASecret";

    public static String generateToken(String username) {
        HashMap<String, Object> map = new HashMap<>();
        //you can put any data in the map
        map.put("username", username);
        String jwt = Jwts.builder()
                .setClaims(map)
                .setExpiration(new Date(System.currentTimeMillis() + 3600_000_000L))// 1000 hour
                .signWith(SignatureAlgorithm.HS512, SECRET)
                .compact();
        return "Bearer "+jwt; //jwt前面一般都會加Bearer
    }

    public static void validateToken(String token) {
        try {
            // parse the token.
            Map<String, Object> body = Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token.replace("Bearer ",""))
                    .getBody();
        }catch (Exception e){
            throw new IllegalStateException("Invalid Token. "+e.getMessage());
        }
    }
}

然後新增登入介面
loginController.java
因為這只是個測試用例,所以也沒連資料庫,使用者密碼檢測就意思一下。

package com.my.swagger2.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.my.swagger2.filter.JwtAuthenticationFilter;
import com.my.swagger2.util.JwtUtil;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping(value="/login")
public class loginController {

    @RequestMapping(value="check", method=RequestMethod.POST)
    @ApiOperation(value="登入身份驗證(JWT驗證)", notes="登入")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "username",value = "使用者名稱稱",required = true,paramType = "form",dataType = "string"),
        @ApiImplicitParam(name = "password",value = "密碼",required = true,paramType = "form",dataType = "string")
    })
    public Object getLoginInfo(HttpServletResponse response,HttpServletRequest request) {
        Account account = new Account();
        account.setUsername(request.getParameter("username").toString());
        account.setPassword(request.getParameter("password").toString());
        if(isValidPassword(account)) {
            String jwt = JwtUtil.generateToken(account.username);
            return new HashMap<String,String>(){{
                put("token", jwt);
            }};
        }else {
            return new ResponseEntity(HttpStatus.UNAUTHORIZED);
        }
    }

    @Bean
    public FilterRegistrationBean jwtFilter() {
        final FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        JwtAuthenticationFilter filter = new JwtAuthenticationFilter();
        registrationBean.setFilter(filter);
        return registrationBean;
    }

    //密碼是否正確
    private boolean isValidPassword(Account ac) {
        Map<String,Object> param = new HashMap<String,Object>();
        param.put("userName", ac.getUsername());
        param.put("password", ac.getPassword());

        return ("test".equals(param.get("userName")))&&("[email protected]".equals(param.get("password")));
    }


    public static class Account {
        private String username;
        private String password;
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
    }   
}

然後修改下之前專案中的
myTestController.java
新增一個驗證碼參@ApiImplicitParam(name = "Authorization",value = "驗證資訊",required = true,paramType = "form",dataType = "string")

@ApiOperation(value="測試資料", notes="獲取字串1+字串2")
    @ApiImplicitParams({
      @ApiImplicitParam(name = "s1", value = "字串1", paramType = "form", dataType = "String"),
      @ApiImplicitParam(name = "s2", value = "字串2", paramType = "form",required = true, dataType = "String"),
      @ApiImplicitParam(name = "Authorization",value = "驗證資訊",required = true,paramType = "form",dataType = "string")
    })
    @RequestMapping(value="/get/info", method=RequestMethod.POST)
    public String getInfo(HttpServletResponse response,HttpServletRequest request) {
        String s1 = request.getParameter("s1");
        String s2 = request.getParameter("s2");

        String result = s1+s2;
        return result;
    }

然後啟動專案測試下
可以看到一個登入介面和一個應用介面
這裡寫圖片描述

嘗試下直接使用應用介面(因為驗證碼設了必填,所以隨便填一個值,當然,也可以設定成非必填,然後不填值,反正最後結果都是一樣的)
這裡寫圖片描述

點選查詢,可以看到報錯,unauthorized,被Jwt攔截下來了。
這裡寫圖片描述

然後嘗試下登入介面,填入剛才在程式碼中設定的使用者密碼,點選查詢
這裡寫圖片描述

可以看到返回了驗證碼,複製驗證碼,填到應用接口裡,嘗試下查詢
這裡寫圖片描述

引數如上,點選查詢
這裡寫圖片描述

成功查詢到資訊了
這裡寫圖片描述

實際使用中直接去request body中取驗證碼會相對不安全,也挺麻煩,可以減少驗證碼有效時間,然後將驗證碼存入session,cookie,或者header中,前兩種可以在驗證登入時在後臺填入,然後攔截器就從session,cookie中去獲取驗證碼,這樣前臺也能不傳驗證碼了,相對也會安全點,畢竟資料傳輸這一環是最危險的,當然cookie在使用者本地,也會相對不安全點,怎麼取捨就要看自己的專案了。

相關推薦

Spring Boot 使用 Jwt + Swagger2 搭建身份驗證介面服務

首先需要搭建好一個Spring Boot + Swagger2的專案 因為之前有寫過 Swagger2 點我 所以這裡就不再重複一遍了。該文章將會在之前專案的基礎上繼續新增整合Jwt。 首先放下搭建完畢的專案目錄結構 pom.xml 在之前的基礎上新

spring boot 整合 swagger2 並定製RestFul API介面

1、新增maven依賴: <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <versi

Spring Boot整合swagger2搭建Restful API線上文件

        Swagger,中文“拽”的意思,它是一個強大的線上API文件的框架,目前它的版本是2.x,所以稱為“swagger2”。swagger2提供了線上文件的查閱和測試功能。利用Swagger2很容易構建RESTf

Spring-bootSwagger2(打造不一樣的api)

plugin itl pid 研究 ssa any cati plugins ast 一、Swagger2是什麽? Swagger 是一款RESTFUL接口的文檔在線自動生成+功能測試功能軟件。 Swagger 是一個規範和完整的框架,用於生成、描述、調用和可視化 RE

Spring Boot框架的搭建

簡化 output 項目依賴 boot jdk1 cat uil prop 自己 一、優點: 1.簡化了配置,是基於Spring4的一套快速開發整合包,減少復雜度 而Spring MVC基於Spring 的一個MVC框架 2.會有一個statrter整合包,減少樣板

spring boot開發環境搭建

oot osi jdbc 宋體 tid mes true err table 軟件151 朱實友 1.新建一個maven項目 Maven配置文件: <!-- Inherit defaults from Spr

Spring Boot的環境搭建

log main函數 ger warn 3.1 集合 font boot col 軟件152 陳卓 一、概念: 從最根本上來講,Spring Boot就是一些庫的集合,它能夠被任意項目的構建系統所使用。簡便起見,該框架也提供了命令行界面,它可以用來運行和測試Boot

spring boot hello world 搭建

-i ref quest img turn stat oid lease void 1.下載地址: Eclipse:http://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/neon

Spring Boot項目搭建

pri resources 以及 urn ext tar tom 管理 tex 1.Spring Boot概述 Spring Boot是由Pivotal團隊提供的全新框架,其設計目的是用來簡化新Spring應用的初始搭建以及開發過程。該框架使用了特定的方式來進行配

Spring Boot 配置swagger2沒有文檔解決方案

post and request oot quest swagger date sele ota @Bean public Docket customImplementation(){ return new Docket(Documentation

Eclipse對spring-bootspring-boot-mybatis的搭建

安裝 OS arch true password username 數據 nbsp maven 1.準備工作 1.1.如果沒有sts(spring tool suite)插件, 則需要下載。 1.1.1.eclipse下載的話,一定要註意版本,因為eclipse會直接下載

Spring Boot 框架的搭建方法(手記)

基本 企業 spring 配置 turn 處理器 control 默認 文件 能夠 一.spring boot歷史背景 Spring 誕生時是 Java 企業版(Java Enterprise Edition,JEE,也稱 J2EE)的 輕量級代替品。無需開發重量級的 En

Spring Boot 整合 swagger2 自動生成 RESTFul API 文檔

pat turn ket config 文件 pen 用戶 配置文件 方式 1)首先編輯pom.xml添加依賴 <dependency>   <groupId>io.springfox</groupId>   <artifactI

Spring BootSwagger2整合

一、Swagger2簡單介紹   Swagger2,它可以輕鬆的整合到Spring Boot中,並與Spring MVC程式配合組織出強大RESTful API文件。它既可以減少我們建立文件的工作量,同時說明內容又整合入實現程式碼中,讓維護文件和修改程式碼整合為一體,可以讓我們在修改程式碼邏輯的同時方便的修

Spring Boot使用AOP搭建統一處理請求日誌和使用log4j記錄不同級別的日誌

受http://blog.didispace.com/springbootaoplog/啟發,今天給Spring Boot專案搭建了統一處理請求日誌的切面並引入log4j記錄不同層級日誌。 mark一下這個過程,以及原文中沒有涉及到的一些疑問 一.  新增要使用的依賴&nbs

Spring Boot整合Swagger2

Spring Boot整合Swagger2 Swagger 介紹 新增入Swagger2的依賴 configuration Swagger 各註解說明 測試 swagger 聚合多個專案 跨域問題 全域性配置

簡易Spring-boot專案的搭建demo

最近剛開始學習Spring-boot框架,從最開始搭建一個Maven工程--配置檔案--測試demo--啟動Spring—boot專案。 1.新建一個maven project(Create a simple project)   2.Next   

Spring-Boot web專案搭建

Spring-Boot快速搭建web專案詳細總結 最近在學習Spring Boot 相關的技術,剛接觸就有種相見恨晚的感覺,因為用spring boot進行專案的搭建是在太方便了,我們往往只需要很簡單的幾步,便可完成一個spring MVC專案的搭建,感覺就是下圖:  好,下

spring boot 的基本使用和短信微服務搭建

eas host sources 重新啟動 tar turn class a pom keys 1.spring boot簡介:   1)spring boot是基於spring開發的,提供了一種快速使用spring的方式,無需xml配置文件   2)解決的問題:   

Spring Boot 配置 Swagger2 介面文件引擎

手寫文件存在的問題 文件需要更新的時候,需要再次傳送一份給前端,也就是文件更新交流不及時。 介面返回結果不明確 不能直接線上測試介面,通常需要使用工具,比如:Postman 介面文件太多,不好管理 使用 Swagger 解決問題 Swagger 也就是為了