# RESTful登入(基於token鑑權)的設計例項
使用場景
現在很多基於restful的api介面都有個登入的設計,也就是在發起正式的請求之前先通過一個登入的請求介面,申請一個叫做token的東西。申請成功後,後面其他的支付請求都要帶上這個token,服務端通過這個token驗證請求的合法性。這個token通常都有一個有效期,一般就是幾個小時。
比如我之前接入過一個支付寶和微信支付的通道,他們提供的api就要求先登入獲取token然後才能使用支付的api介面。
在比如微信的公眾平臺介面,關鍵的介面在使用之前都要帶access token。access_token是公眾號的全域性唯一票據,有效期為7200秒,重複獲取將導致上次獲取的access_token失效。
介面呼叫請求說明
http請求方式: GET
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
引數說明
引數 是否必須 說明
grant_type 是 獲取access_token填寫client_credential
appid 是 第三方使用者唯一憑證
secret 是 第三方使用者唯一憑證金鑰,既appsecret
返回說明
正常情況下,微信會返回下述JSON資料包給公眾號:
{"access_token":"ACCESS_TOKEN","expires_in":7200}
引數 說明
access_token 獲取到的憑證
expires_in 憑證有效時間,單位:秒
錯誤時微信會返回錯誤碼等資訊,JSON資料包示例如下(該示例為AppID無效錯誤):
{"errcode":40013,"errmsg":"invalid appid"}
什麼是JWT(json web token)
首先說它是一種規範。目的是在客戶端和服務端之間定義一種鑑權行為從而保證資料傳遞的安全性。
JWT 標準的 Token 有三個部分:
- header
- payload
- signature
-
中間用點分隔開,並且都會使用 Base64 編碼,所以真正的 Token 看起來像這樣:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc
關於三個部分具體都是些什麼東西,大家自行搜尋即可,不是我這篇文章的重點。
我們說restful API中使用的token鑑權機制,大部分都是遵循JWT規範的,也就是底層都是對JWT的具體實現。
一個java實現例項
說了這麼多,該上例項了。這個例項會用到redis,spring等技術。
這個例項原出處:
RESTful登入設計(基於Spring及Redis的Token鑑權)
原專案是基於maven的。我這裡為了除錯方便把專案遷移到myeclipse中,關於如何匯入到myeclipse中,請參考:
上面的連結中對程式碼解釋的也比較清楚了。我這裡只說下如何執行測試效果。
根據本地實際情況修改mysql和redis配置
這個工程其實是個基於spring boot的專案,Spring boot 的預設配置檔案是 resources 下的 application.properties。所以我們主要是修改它。
其中spring.datasource.*的配置項是mysql相關的,這裡解釋下。有人可能有疑問為什麼程式裡並沒有看到引用這些配置變數。這是因為spring boot是一種約定優於配置的開發框架。比如,
spring.datasource.username就是表示資料庫使用者名稱,你不能隨便改,框架裡就用它作為查抄依據。
同理spring.redis.*也是redis相關的配置。
上面幾個地方要根據你本地實際情況修改。修改完之後,在你的mysql中新建一個名為demo的資料庫(如果原來沒有的話)。然後執行工程中init.sql中的語句,這是為了初始化表。
執行
首先執行右鍵專案目錄,run as -> maven install,會看到類似下面的輸出:
然後再執行 run as -> java application, 然後選擇程式的入口:
同樣看下console有沒有錯誤,如果報錯通常是上面的配置不對,仔細檢查下。
開啟瀏覽器,輸入http://localhost:8080,顯示如下:
表明執行成功。
測試下登入,
登入成功,並且也成功的建立了token。
退出登入,在authorization中填寫用userId和token以”_”拼接得到的字串。
有人會問為什麼authorization需要這樣的格式才能退出登入成功。下面的程式碼可以說明問題,
...
@RequestMapping(method = RequestMethod.DELETE)
@Authorization
public ResponseEntity logout(@CurrentUser User user) {
tokenManager.deleteToken(user.getId());
return new ResponseEntity<>(ResultModel.ok(), HttpStatus.OK);
}
@Authorization用於表示該操作需要登入後才能進行,否則會返回401錯誤。如下:
...
//驗證token
TokenModel model = manager.getToken(authorization);
if (manager.checkToken(model)) {
//如果token驗證成功,將token對應的使用者id存在request中,便於之後注入
request.setAttribute(Constants.CURRENT_USER_ID, model.getUserId());
return true;
}
//如果驗證token失敗,並且方法註明了Authorization,返回401錯誤
if (method.getAnnotation(Authorization.class) != null) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return false;
}
為了驗證redis的快取有效期,我把程式碼做了一點修改,過期時間設定成1分鐘便於測試。
/**
* token有效期(分鐘)
*/
public static final int TOKEN_EXPIRES_MINS = 1;
public TokenModel createToken(long userId) {
//使用uuid作為源token
String token = UUID.randomUUID().toString().replace("-", "");
TokenModel model = new TokenModel(userId, token);
//儲存到redis並設定過期時間
// redis.boundValueOps(userId).set(token, Constants.TOKEN_EXPIRES_HOUR, TimeUnit.HOURS);
redis.boundValueOps(userId).set(token, Constants.TOKEN_EXPIRES_MINS, TimeUnit.MINUTES);
return model;
}
然後我先登入,等超過一分鐘再退出登入,確認會返回401錯誤。
相關文章
- restful風格請求,基於token鑑權例項REST
- 含有token鑑權的介面專案使用unittest框架設計測試登入,充值的介面框架
- 登陸鑑權方案設計
- MongoDB 6.0 單例項基於使用者角色實現授權登入MongoDB單例
- jwt與session的登入鑑權JWTSession
- 實現基於JWT的Token登入驗證功能JWT
- Laravel Passport 之api登入鑑權LaravelPassportAPI
- python--介面自動化鑑權例項Python
- restful鑑權白名單匹配urlREST
- oracle 12C的例項登入設計很腦殘吧Oracle
- MyBatis基於Maven入門例項MyBatisMaven
- BS系統的登入鑑權流程演變
- 基於Token認證的多點登入和WebApi保護WebAPI
- golang 基於 jwt 實現的登入授權GolangJWT
- token 登入
- Blazor OIDC 單點登入授權例項7 - Blazor hybird app 端授權BlazorAPP
- 基於C#的簡單登入窗體設計C#
- 基於工程經驗的『RESTful介面設計規範』REST
- PHP如何實現登入認證和鑑權PHP
- Next.js-Cookie鑑權+續期+退出登入JSCookie
- 基於vue 做了關於token驗證的例項,和移動端下fixed失效的解決方案Vue
- 手把手教會你小程式登入鑑權
- window下通過Xshell登入GCP計算機例項GC計算機
- 短影片app開發,可以借鑑的幾個登入介面設計APP
- 基於RBAC的許可權設計模型模型
- JWT實現登入認證例項JWT
- Hibernate基於Maven入門例項,與MyBatis比對MavenMyBatis
- Composer 使用 JWT 生成 TOKEN 例項JWT
- JWT登入鑑權:避免在使用者操作的過程中JWT到期跳轉登入JWT
- 關於QQ授權登入
- JWT+Interceptor實現無狀態登入和鑑權JWT
- 聲網 Token 鑑權機制,以及常見的問題
- 如何在SpringBoot中整合JWT(JSON Web Token)鑑權Spring BootJWTJSONWeb
- 153 多方式登入簽發token&單項/多項的增刪查改
- 基於laravel的事件監聽例項Laravel事件
- 基於Taro框架的微信小程式JWT授權登入方案框架微信小程式JWT
- 基於位運算的許可權設計
- sql 注入越過登入驗證例項SQL
- PHP 中基於 Casbin 做 RBAC + RESTful 許可權控制PHPREST