3行程式碼快速實現Spring Boot Oauth2 Server服務
這裡的3行程式碼並不是指真的只需要寫3行程式碼,而是基於我已經寫好的一個Spring Boot Oauth2服務。僅僅需要修改3行資料庫配置資訊,即可得到一個Spring Boot Oauth2服務。
專案地址https://github.com/jeesun/oauthserver
oauthserver
簡介
oauthserver是一個基於Spring Boot Oauth2的完整的獨立的Oauth微服務。僅僅需要建立相關資料表,修改資料庫的連線資訊,你就可以得到一個Oauth微服務。
支援的關係型資料庫:
- PostgreSQL
- MySQL
已實現的功能:
1. 整合Spring Boot Oauth2,實現Oauth服務;
2. token儲存到關係型資料庫;
3. 獲取token時,username允許傳使用者名稱、手機號或者郵箱;
4. 日誌記錄儲存到檔案,並按日歸檔;
5. 資料庫連線資訊加密;
6. 整合Druid資料庫連線池;
7. 自定義Oauth2Exception異常返回的json資訊。
更新日誌
v1.1.0(2018-06-01)
- 自定義Oauth2Exception異常返回的json資訊。
v1.0.3
- bug修復。
v1.0.1
- 獲取token時,username允許傳使用者名稱、手機號或者郵箱。
v1.0.0
- 完成基礎Oauth服務。
使用流程
1. 建表
- PostgreSQL
請執行src/main/resources/schema-pg.sql
,完成資料表的建立和測試資料的匯入。 - MySQL
請執行src/main/resources/schema-mysql.sql
,完成資料表的建立和測試資料的匯入。
2. 修改資料庫連線資訊
在application.yml中,配置著資料庫的連線資訊。其中,配置項username和password是要經過jasypt加密的,不能直接填明文。加密金鑰由jasypt.encryptor.password
- PostgreSQL
# PostgreSQL連線資訊
driver-class-name: org.postgresql.Driver
url: jdbc:postgresql://127.0.0.1:5432/thymelte?useUnicode=true&characterEncoding=UTF-8
username: ENC(hTpbG9fq+7P3SntmXuNtDxbtWDqRuPV+) #明文postgres
password: ENC(abdq6LyOspryFQHCqzEMTxRozyJVjIA4) #明文19961120
- MySQL
# MySQL連線資訊
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: ENC(YiYjVwTulDGN//YaB3KbuA==) #明文root
password: ENC(9oaIJkFgGSDFaHH3OXY63RHWQ+amDmiJ) #明文19941017
3. 執行
現在,一切已準備就緒。執行專案,當程式成功啟動時,即表明你已配置成功。
4. 測試
在建表時,我已經向表添加了測試資料。以下請求引數的值,均是測試資料,在資料表中可以找得到。請根據需求到資料表中修改對應的值。
在表oauth_client_details
表中,已有一條測試資料。列client_id
和client_secret
的值,分別對應Basic Oauth的請求引數username
和password
的值。而列access_token_validity
和列refresh_token_validity
,分別代表access_token和refresh_token的有效期時間,以秒為單位。測試資料7200和5184000,分別代表2個小時和2個月(60天)。這是一個比較合理的有效期時間的設定,可以參考。
token相關的介面,都需要進行Basic Oauth認證。
如下圖所示:
1、根據使用者名稱和密碼獲取access_token
POST http://localhost:8182/oauth/token?grant_type=password&username=jeesun&password=1234567890c
成功示例
status=200,返回的json資料:
{
"access_token": "ca582cd1-be6c-4a5a-82ec-10af7a8e06eb",
"token_type": "bearer",
"refresh_token": "c24a6143-97c8-4642-88b9-d5c5b902b487",
"expires_in": 3824,
"scope": "read write trust"
}
失敗示例
1. 使用者名稱錯誤
status=400,返回的json資料:
{
"code": 400,
"message": "使用者名稱不存在",
"data": null
}
- 密碼錯誤
status=400,返回的json資料:
{
"code": 400,
"message": "密碼錯誤",
"data": null
}
- 賬號被封enabled=false
status=400,返回的json資料:
{
"code": 400,
"message": "您已被封號",
"data": null
}
2、檢查access_token
GET http://localhost:8182/oauth/check_token?token=ca582cd1-be6c-4a5a-82ec-10af7a8e06eb
成功示例
即使使用者被封enabled=false,access_token未過期仍然可用。
status=200,返回的json資料:
{
"aud": [
"oauth2-resource"
],
"exp": 1524507296,
"user_name": "jeesun",
"authorities": [
"ROLE_ADMIN",
"ROLE_USER"
],
"client_id": "clientIdPassword",
"scope": [
"read",
"write",
"trust"
]
}
失敗示例
access_token已過期
status=400,返回的json資料:
{
"code": 400,
"message": "Token was not recognised",
"data": null
}
3、根據refresh_token獲取新的access_token
成功示例
status=200,返回的json資料:
{
"access_token": "690ecd7d-f2b7-4faa-ac45-5b7a319478e8",
"token_type": "bearer",
"refresh_token": "c24a6143-97c8-4642-88b9-d5c5b902b487",
"expires_in": 7199,
"scope": "read write trust"
}
失敗示例
使用者被封enabled=false
status=401,返回的json資料:
{
"code": 401,
"msg": "使用者已失效",
"data": null
}
app實踐指南
app獲取到token資訊後,需要儲存token資訊和請求時間。在傳access_token之前,需要檢查access_token是否過期。為了減少後臺壓力,檢查access_token是否過期應該是在app本地完成。通過token的keyexpires_in
(剩餘有效期)的值,以及本地記錄的請求時間,和當前時間做對比,可以很方便地判斷出access_token是否過期。如果過期了,需要通過refresh_token獲取新的access_token。因為access_token的有效期只有2個小時,這個驗證是必須的。
refresh_token同理。