国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 利用JWT如何實現對API的授權訪問詳解

利用JWT如何實現對API的授權訪問詳解

2021-05-31 11:35Decouple Java教程

這篇文章主要給大家介紹了關于利用JWT如何實現對API的授權訪問的相關資料,需要的朋友可以參考下

什么是jwt

jwt(json web token)是一個開放標準(rfc 7519),它定義了一種緊湊且獨立的方式,可以在各個系統之間用json作為對象安全地傳輸信息,并且可以保證所傳輸的信息不會被篡改。

「jwt」由三部分構成

  • 信息頭:指定了使用的簽名算法
  • 聲明部分:其中也可以包含超時時間
  • 基于指定的算法生成的簽名

通過這三部分信息,api 服務端可以根據「jwt」信息頭和聲明部分的信息重新生成簽名。之所以可以這樣做,是因為生成簽名需要的秘鑰存放在服務器端。

?
1
jwtauth.new("hs256", []byte("k8uemdpyb9awfkzs"), nil)

如果這個簽名秘鑰比較簡單,建議立刻換一個復雜一些的,更改以后會使所有已經產生的「jwt」 失效,強制客戶端重新從服務器獲取授權。

jwt通常有兩種應用場景:

  • 授權。這是最常見的jwt使用場景。一旦用戶登錄,每個后續請求將包含一個jwt,作為該用戶訪問資源的令牌。
  • 信息交換??梢岳胘wt在各個系統之間安全地傳輸信息,jwt的特性使得接收方可以驗證收到的內容是否被篡改。

本文討論第一點,如何利用jwt來實現對api的授權訪問。這樣就只有經過授權的用戶才可以調用api。

jwt的結構

利用JWT如何實現對API的授權訪問詳解

jwt由三部分組成,用.分割開。

header

第一部分為header,通常由兩部分組成:令牌的類型,即jwt,以及所使用的加密算法。

?
1
2
3
4
{
 "alg": "hs256",
 "typ": "jwt"
}

base64加密后,就變成了:

eyjhbgcioijiuzi1niisinr5cci6ikpxvcj9

payload

第二部分為payload,里面可以放置自定義的信息,以及過期時間、發行人等。

?
1
2
3
4
5
{
 "sub": "1234567890",
 "name": "john doe",
 "iat": 1516239022
}

base64加密后,就變成了:

eyjzdwiioiixmjm0nty3odkwiiwibmftzsi6ikpvag4grg9liiwiawf0ijoxnte2mjm5mdiyfq

signature

第三部分為signature,計算此簽名需要四部分信息:

  • header里的算法信息
  • header
  • payload
  • 一個自定義的秘鑰

接受到jwt后,利用相同的信息再計算一次簽名,然年與jwt中的簽名對比,如果不相同則說明jwt中的內容被篡改。

解碼后的jwt

利用JWT如何實現對API的授權訪問詳解

將上面三部分都編碼后再合在一起就得到了jwt。

需要注意的是,jwt的內容并不是加密的,只是簡單的base64編碼。也就是說,jwt一旦泄露,里面的信息可以被輕松獲取,因此不應該用jwt保存任何敏感信息。

jwt是怎樣工作的

利用JWT如何實現對API的授權訪問詳解

  • 應用程序或客戶端向授權服務器請求授權。這里的授權服務器可以是單獨的一個應用,也可以和api集成在同一個應用里。
  • 授權服務器向應用程序返回一個jwt。
  • 應用程序將jwt放入到請求里(通常放在http的authorization頭里)
  • 服務端接收到請求后,驗證jwt并執行對應邏輯。

在java里使用jwt

引入依賴

?
1
2
3
4
<dependency>
 <groupid>io.jsonwebtoken</groupid>
 <artifactid>jjwt</artifactid>
</dependency>

這里使用了一個叫jjwt(java jwt)的庫。

jwt service

生成jwt

?
1
2
3
4
5
6
7
public string generatetoken(string payload) {
  return jwts.builder()
    .setsubject(payload)
    .setexpiration(new date(system.currenttimemillis() + 10000))
    .signwith(signaturealgorithm.hs256, secret_key)
    .compact();
 }

這里設置過期時間為10秒,因此生成的jwt只在10秒內能通過驗證。

需要提供一個自定義的秘鑰。

解碼jwt

?
1
2
3
4
5
6
7
public string parsetoken(string jwt) {
  return jwts.parser()
    .setsigningkey(secret_key)
    .parseclaimsjws(jwt)
    .getbody()
    .getsubject();
 }

解碼時會檢查jwt的簽名,因此需要提供秘鑰。

驗證jwt

?
1
2
3
4
5
6
7
8
public boolean istokenvalid(string jwt) {
  try {
   parsetoken(jwt);
  } catch (throwable e) {
   return false;
  }
  return true;
 }

jjwt并沒有提供判斷jwt是否合法的方法,但是在解碼非法jwt時會拋出異常,因此可以通過捕獲異常的方式來判斷是否合法。

注冊/登錄

?
1
2
3
4
5
6
7
@getmapping("/registration")
 public string register(@requestparam string username, httpservletresponse response) {
  string jwt = jwtservice.generatetoken(username);
  response.setheader(jwt_header_name, jwt);
 
  return string.format("jwt for %s :\n%s", username, jwt);
 }

需要為還沒有獲取到jwt的用戶提供一個這樣的注冊或者登錄入口,來獲取jwt。

獲取到響應里的jwt后,要在后續的請求里包含jwt,這里放在請求的authorization頭里。

驗證jwt

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@override
public void dofilter(servletrequest request, servletresponse response, filterchain chain) throws ioexception, servletexception {
  httpservletrequest httpservletrequest = (httpservletrequest) request;
  httpservletresponse httpservletresponse = (httpservletresponse) response;
 
  string jwt = httpservletrequest.getheader(jwt_header_name);
  if (white_list.contains(httpservletrequest.getrequesturi())) {
   chain.dofilter(request, response);
  } else if (istokenvalid(jwt)) {
   updatetoken(httpservletresponse, jwt);
   chain.dofilter(request, response);
  } else {
   httpservletresponse.senderror(httpservletresponse.sc_unauthorized);
  }
 }
 
private void updatetoken(httpservletresponse httpservletresponse, string jwt) {
  string payload = jwtservice.parsetoken(jwt);
  string newtoken = jwtservice.generatetoken(payload);
  httpservletresponse.setheader(jwt_header_name, newtoken);
 }

將驗證操作放在filter里,這樣除了登錄入口,其它的業務代碼將感覺不到jwt的存在。

將登錄入口放在white_list里,跳過對這些入口的驗證。

需要刷新jwt。如果jwt是合法的,那么應該用同樣的payload來生成一個新的jwt,這樣新的jwt就會有新的過期時間,用此操作來刷新jwt,以防過期。

如果使用filter,那么刷新的操作要在調用dofilter()之前,因為調用之后就無法再修改response了。

api

?
1
2
3
4
5
6
7
8
9
private final static string jwt_header_name = "authorization";
 
 @getmapping("/api")
 public string testapi(httpservletrequest request, httpservletresponse response) {
  string oldjwt = request.getheader(jwt_header_name);
  string newjwt = response.getheader(jwt_header_name);
 
  return string.format("your old jwt is:\n%s \nyour new jwt is:\n%s\n", oldjwt, newjwt);
 }

這時候api就處于jwt的保護下了。api可以完全不用感知到jwt的存在,同時也可以主動獲取jwt并解碼,以得到jwt里的信息。如上所示。

尾注

完整的demo可以在這里找到:https://github.com/beginner258/jwt-demo

參考資料:https://jwt.io/

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://www.cnblogs.com/xz816111/p/9620139.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 羞羞视频免费 | 免费看国产 | 精品久久久久久久 | 夜夜摸夜夜操 | 精品一区二区三区免费 | 影音先锋亚洲精品 | 亚洲国产免费 | 久色视频在线观看 | 国产一区二区三区在线免费 | 一区二区中文字幕 | 三区视频| 日本成片视频 | 久草.com| 希岛爱理在线 | 国产综合在线观看视频 | 精品国偷自产国产一区 | 91麻豆精品国产91久久久更新资源速度超快 | 午夜精品久久久久久久久久久久 | 一本一本久久a久久精品综合妖精 | 国产一区二区三区四 | 九九九色 | 黄色免费在线观看 | 欧美中文字幕一区二区三区 | 欧美一区二区免费在线观看 | 精品一区二区三区久久 | a级在线观看 | 国产激情精品视频 | 欧美日韩一区二区三区免费视频 | 久久天堂电影 | 日韩精品免费视频 | 精品久久久久国产 | 午夜影院网站 | 伊人网在线视频免费观看 | 久久久天天 | 精品在线一区 | 九九综合九九 | 欧美在线观看www | 国产黄色电影 | 伊人久久综合精品一区二区三区 | 国产一区二区三区 | 91久久精品日日躁夜夜躁国产 |